axiomancer-mechanics 0.1.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 (152) hide show
  1. package/README.md +124 -0
  2. package/dist/Character/index.d.ts +13 -0
  3. package/dist/Character/index.d.ts.map +1 -0
  4. package/dist/Character/index.js +26 -0
  5. package/dist/Character/index.js.map +1 -0
  6. package/dist/Combat/advantage.d.ts +5 -0
  7. package/dist/Combat/advantage.d.ts.map +1 -0
  8. package/dist/Combat/advantage.js +27 -0
  9. package/dist/Combat/advantage.js.map +1 -0
  10. package/dist/Combat/combat.reducer.d.ts +16 -0
  11. package/dist/Combat/combat.reducer.d.ts.map +1 -0
  12. package/dist/Combat/combat.reducer.js +48 -0
  13. package/dist/Combat/combat.reducer.js.map +1 -0
  14. package/dist/Combat/damage.d.ts +4 -0
  15. package/dist/Combat/damage.d.ts.map +1 -0
  16. package/dist/Combat/damage.js +16 -0
  17. package/dist/Combat/damage.js.map +1 -0
  18. package/dist/Combat/dice.d.ts +9 -0
  19. package/dist/Combat/dice.d.ts.map +1 -0
  20. package/dist/Combat/dice.js +13 -0
  21. package/dist/Combat/dice.js.map +1 -0
  22. package/dist/Combat/e2e/combat.engine.d.ts +17 -0
  23. package/dist/Combat/e2e/combat.engine.d.ts.map +1 -0
  24. package/dist/Combat/e2e/combat.engine.js +118 -0
  25. package/dist/Combat/e2e/combat.engine.js.map +1 -0
  26. package/dist/Combat/effects.d.ts +24 -0
  27. package/dist/Combat/effects.d.ts.map +1 -0
  28. package/dist/Combat/effects.js +97 -0
  29. package/dist/Combat/effects.js.map +1 -0
  30. package/dist/Combat/health.d.ts +13 -0
  31. package/dist/Combat/health.d.ts.map +1 -0
  32. package/dist/Combat/health.js +21 -0
  33. package/dist/Combat/health.js.map +1 -0
  34. package/dist/Combat/index.d.ts +16 -0
  35. package/dist/Combat/index.d.ts.map +1 -0
  36. package/dist/Combat/index.js +69 -0
  37. package/dist/Combat/index.js.map +1 -0
  38. package/dist/Combat/resist.d.ts +4 -0
  39. package/dist/Combat/resist.d.ts.map +1 -0
  40. package/dist/Combat/resist.js +94 -0
  41. package/dist/Combat/resist.js.map +1 -0
  42. package/dist/Combat/stats.d.ts +7 -0
  43. package/dist/Combat/stats.d.ts.map +1 -0
  44. package/dist/Combat/stats.js +39 -0
  45. package/dist/Combat/stats.js.map +1 -0
  46. package/dist/Effects/buffs.library.json +944 -0
  47. package/dist/Effects/debuffs.library.json +1210 -0
  48. package/dist/Effects/effects.library.d.ts +10 -0
  49. package/dist/Effects/effects.library.d.ts.map +1 -0
  50. package/dist/Effects/effects.library.js +20 -0
  51. package/dist/Effects/effects.library.js.map +1 -0
  52. package/dist/Effects/index.d.ts +28 -0
  53. package/dist/Effects/index.d.ts.map +1 -0
  54. package/dist/Effects/index.js +144 -0
  55. package/dist/Effects/index.js.map +1 -0
  56. package/dist/Enemy/enemy.library.d.ts +5 -0
  57. package/dist/Enemy/enemy.library.d.ts.map +1 -0
  58. package/dist/Enemy/enemy.library.js +23 -0
  59. package/dist/Enemy/enemy.library.js.map +1 -0
  60. package/dist/Enemy/enemy.logic.d.ts +5 -0
  61. package/dist/Enemy/enemy.logic.d.ts.map +1 -0
  62. package/dist/Enemy/enemy.logic.js +23 -0
  63. package/dist/Enemy/enemy.logic.js.map +1 -0
  64. package/dist/Enemy/index.d.ts +24 -0
  65. package/dist/Enemy/index.d.ts.map +1 -0
  66. package/dist/Enemy/index.js +24 -0
  67. package/dist/Enemy/index.js.map +1 -0
  68. package/dist/Game/actions.constants.d.ts +10 -0
  69. package/dist/Game/actions.constants.d.ts.map +1 -0
  70. package/dist/Game/actions.constants.js +12 -0
  71. package/dist/Game/actions.constants.js.map +1 -0
  72. package/dist/Game/game-mechanics.constants.d.ts +18 -0
  73. package/dist/Game/game-mechanics.constants.d.ts.map +1 -0
  74. package/dist/Game/game-mechanics.constants.js +25 -0
  75. package/dist/Game/game-mechanics.constants.js.map +1 -0
  76. package/dist/Game/game.reducer.d.ts +4 -0
  77. package/dist/Game/game.reducer.d.ts.map +1 -0
  78. package/dist/Game/game.reducer.js +20 -0
  79. package/dist/Game/game.reducer.js.map +1 -0
  80. package/dist/Game/index.d.ts +9 -0
  81. package/dist/Game/index.d.ts.map +1 -0
  82. package/dist/Game/index.js +28 -0
  83. package/dist/Game/index.js.map +1 -0
  84. package/dist/Game/persistence/node.adapter.d.ts +3 -0
  85. package/dist/Game/persistence/node.adapter.d.ts.map +1 -0
  86. package/dist/Game/persistence/node.adapter.js +28 -0
  87. package/dist/Game/persistence/node.adapter.js.map +1 -0
  88. package/dist/Game/persistence/null.adapter.d.ts +3 -0
  89. package/dist/Game/persistence/null.adapter.d.ts.map +1 -0
  90. package/dist/Game/persistence/null.adapter.js +8 -0
  91. package/dist/Game/persistence/null.adapter.js.map +1 -0
  92. package/dist/Game/persistence/types.d.ts +6 -0
  93. package/dist/Game/persistence/types.d.ts.map +1 -0
  94. package/dist/Game/persistence/types.js +3 -0
  95. package/dist/Game/persistence/types.js.map +1 -0
  96. package/dist/Game/store.d.ts +27 -0
  97. package/dist/Game/store.d.ts.map +1 -0
  98. package/dist/Game/store.js +56 -0
  99. package/dist/Game/store.js.map +1 -0
  100. package/dist/Items/index.d.ts +3 -0
  101. package/dist/Items/index.d.ts.map +1 -0
  102. package/dist/Items/index.js +16 -0
  103. package/dist/Items/index.js.map +1 -0
  104. package/dist/Items/item.reducer.d.ts +8 -0
  105. package/dist/Items/item.reducer.d.ts.map +1 -0
  106. package/dist/Items/item.reducer.js +38 -0
  107. package/dist/Items/item.reducer.js.map +1 -0
  108. package/dist/Items/types.d.ts +31 -0
  109. package/dist/Items/types.d.ts.map +1 -0
  110. package/dist/Items/types.js +19 -0
  111. package/dist/Items/types.js.map +1 -0
  112. package/dist/NPCs/index.d.ts +2 -0
  113. package/dist/NPCs/index.d.ts.map +1 -0
  114. package/dist/NPCs/index.js +3 -0
  115. package/dist/NPCs/index.js.map +1 -0
  116. package/dist/Skills/index.d.ts +2 -0
  117. package/dist/Skills/index.d.ts.map +1 -0
  118. package/dist/Skills/index.js +3 -0
  119. package/dist/Skills/index.js.map +1 -0
  120. package/dist/Utils/index.d.ts +20 -0
  121. package/dist/Utils/index.d.ts.map +1 -0
  122. package/dist/Utils/index.js +95 -0
  123. package/dist/Utils/index.js.map +1 -0
  124. package/dist/Utils/typeGuards.d.ts +10 -0
  125. package/dist/Utils/typeGuards.d.ts.map +1 -0
  126. package/dist/Utils/typeGuards.js +15 -0
  127. package/dist/Utils/typeGuards.js.map +1 -0
  128. package/dist/World/Continents/Coastal-Village/maps.d.ts +6 -0
  129. package/dist/World/Continents/Coastal-Village/maps.d.ts.map +1 -0
  130. package/dist/World/Continents/Coastal-Village/maps.js +48 -0
  131. package/dist/World/Continents/Coastal-Village/maps.js.map +1 -0
  132. package/dist/World/index.d.ts +11 -0
  133. package/dist/World/index.d.ts.map +1 -0
  134. package/dist/World/index.js +39 -0
  135. package/dist/World/index.js.map +1 -0
  136. package/dist/World/map.library.d.ts +5 -0
  137. package/dist/World/map.library.d.ts.map +1 -0
  138. package/dist/World/map.library.js +3 -0
  139. package/dist/World/map.library.js.map +1 -0
  140. package/dist/World/quest.library.d.ts +8 -0
  141. package/dist/World/quest.library.d.ts.map +1 -0
  142. package/dist/World/quest.library.js +3 -0
  143. package/dist/World/quest.library.js.map +1 -0
  144. package/dist/World/world.reducer.d.ts +10 -0
  145. package/dist/World/world.reducer.d.ts.map +1 -0
  146. package/dist/World/world.reducer.js +78 -0
  147. package/dist/World/world.reducer.js.map +1 -0
  148. package/dist/index.d.ts +24 -0
  149. package/dist/index.d.ts.map +1 -0
  150. package/dist/index.js +136 -0
  151. package/dist/index.js.map +1 -0
  152. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # Axiomancer — Mechanics Engine
2
+
3
+ Turn-based RPG engine with a Heart / Body / Mind combat system. Status effects, skills, and enemies are themed around logical fallacies and philosophical paradoxes.
4
+
5
+ This repository is the **non-UI engine** only. It is consumed as a library by clients (e.g. a React Native app). All logic is exposed through the package barrel at [`src/index.ts`](./src/index.ts).
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ The package is not yet published. To consume it locally:
12
+
13
+ ```bash
14
+ npm install
15
+ npm run build # compiles to ./dist
16
+ ```
17
+
18
+ ## Quick start
19
+
20
+ ```ts
21
+ import {
22
+ createCharacter, createEnemy,
23
+ createGameStore, nullAdapter,
24
+ determineEnemyAction, determineAdvantage,
25
+ applyDamage, getAttackStat, getDefenseStat,
26
+ applyTier1CombatEffect, lookupEffect,
27
+ isCombatOngoing,
28
+ } from 'axiomancer-mechanics';
29
+
30
+ const player = createCharacter({
31
+ name: 'Hero',
32
+ level: 1,
33
+ baseStats: { heart: 4, body: 3, mind: 2 },
34
+ });
35
+
36
+ const enemy = createEnemy({
37
+ id: 'goblin-1',
38
+ name: 'Goblin',
39
+ description: '',
40
+ level: 1,
41
+ baseStats: { heart: 1, body: 2, mind: 1 },
42
+ mapName: 'fishing-village',
43
+ logic: 'random',
44
+ });
45
+
46
+ const store = createGameStore(nullAdapter, { player });
47
+ store.getState().startCombat(enemy);
48
+
49
+ while (isCombatOngoing(store.getState().combat!)) {
50
+ // ...drive a round of combat using the helpers above...
51
+ }
52
+ ```
53
+
54
+ ## Public API
55
+
56
+ The barrel exports are organised by domain:
57
+
58
+ | Group | Highlights |
59
+ | ---------- | ------------------------------------------------------------------------------------------------------------ |
60
+ | Character | `createCharacter`, `Character`, `BaseStats`, `DerivedStats`, `NonCombatStats` |
61
+ | Enemy | `createEnemy`, `Enemy`, `EnemyLogic`, `Tier1EffectOverrides`, `randomLogic`, `decideEnemyAction` |
62
+ | Combat | `determineAdvantage`, `getBaseStat`/`getAttackStat`/`getDefenseStat`/`getSaveStat`/`getResistStat`, `applyDamage`, `heal`, `tickAllEffects`, `applyRegen`, `getActiveRollModifier`, `getThornsReflect`, `resolveEffectApplication`, `Stance`, `Action`, `CombatState`, `Combatant` |
63
+ | Combat reducer | `initializeCombat`, `setPhase`, `setPlayerStance`, `setPlayerAction`, `appendLog`, `incrementFriendship`, `endCombat` |
64
+ | Effects | `applyEffect`, `applyTier1CombatEffect`, `clearTier1EffectsForStance`, `lookupEffect`, `Effect`, `ActiveEffect`, `EffectTier` |
65
+ | Items | `addItem`, `removeItem`, `useConsumable`, `stackItem`, `Item` and its variants, type guards |
66
+ | Game | `createGameStore`, `GameState`, persistence adapters, mechanic constants |
67
+ | World | `createStartingWorld`, world reducer (map/node/continent transitions), `WorldState`, `WorldMap` |
68
+ | Utils | `clamp`, `randomInt`, `deepClone`, `deriveStats`, `calculateMaxHealth`, `createDieRoll`, `isCharacter`, `isEnemy` |
69
+
70
+ ## CLIs
71
+
72
+ The repo also ships two CLIs for hands-on testing. They are NOT part of the published package surface (`src/CLI` is excluded from the build):
73
+
74
+ | Command | What it does |
75
+ | ------------------ | ------------------------------------------------------- |
76
+ | `npm run combat` | Interactive combat against the sample `Disatree` enemy. |
77
+ | `npm run character`| Interactive character builder. |
78
+ | `npm run combat:auto` | `pexpect`-driven smoke test of the combat CLI. |
79
+
80
+ ## Project layout
81
+
82
+ ```
83
+ src/
84
+ index.ts # public barrel
85
+ Character/ # createCharacter + Character types
86
+ Combat/ # advantage, stats, dice, damage, health, effects, resist, reducer
87
+ Effects/ # applyEffect, Tier 1 stance effects, library lookup
88
+ Enemy/ # createEnemy + AI logic + library
89
+ Game/ # store + persistence + constants + actions + reducer
90
+ Items/ # inventory reducers + item types
91
+ Skills/ # types only (engine pending)
92
+ World/ # world state, reducers, map and quest libraries
93
+ NPCs/ # NPC types
94
+ Utils/ # math, dice, stat derivation, type guards
95
+ CLI/ # interactive CLIs (not exported by the package)
96
+ docs/ # design notes per system
97
+ docs/effects/ # one markdown per buff/debuff
98
+ docs/references/ # source material (fallacies, paradoxes, pantheon, Mörk Borg)
99
+ specs/ # planning specs for upcoming work (Phase 2 onward)
100
+ automation/ # python combat-CLI test harness
101
+ ```
102
+
103
+ ## Documentation
104
+
105
+ - [`GAME-ROADMAP.md`](./GAME-ROADMAP.md) — phased development plan with progress tracking
106
+ - [`AUDIT.md`](./AUDIT.md) — code audit and quality assessment
107
+ - [`Knowledge-Gaps.md`](./Knowledge-Gaps.md) — open design and intent questions
108
+ - [`BRAINDUMP.md`](./BRAINDUMP.md) — unorganised idea backlog
109
+ - [`specs/`](./specs) — phased planning specs to drive the next round of work (start with `specs/README.md`)
110
+ - [`docs/`](./docs) — per-system references (combat, effects, character, world, etc.)
111
+ - [`docs/effects/`](./docs/effects) — per-effect deep-dives (one file per buff/debuff)
112
+ - [`docs/references/`](./docs/references) — source material (fallacies, paradoxes, pantheon, story)
113
+
114
+ ## Scripts
115
+
116
+ | Script | What it does |
117
+ | --------------------- | ---------------------------------- |
118
+ | `npm run build` | Type-check and compile to `dist/` |
119
+ | `npm run type-check` | Type-check only |
120
+ | `npm test` | Run the vitest suite |
121
+ | `npm run test:watch` | Vitest in watch mode |
122
+ | `npm run lint` | Run ESLint (currently broken — see [`AUDIT.md`](./AUDIT.md) Concern 7) |
123
+ | `npm run check` | Lint + type-check |
124
+ | `npm run combat:auto` | Python harness driving the combat CLI N times |
@@ -0,0 +1,13 @@
1
+ import { Character, BaseStats } from './types';
2
+ import { ActiveEffect } from '../Effects/types';
3
+ import { Item } from '../Items/types';
4
+ export interface CreateCharacterOptions {
5
+ name: string;
6
+ level: number;
7
+ baseStats: BaseStats;
8
+ inventory?: Item[];
9
+ effects?: ActiveEffect[];
10
+ }
11
+ export declare function createCharacter(options: CreateCharacterOptions): Character;
12
+ export type { Character, BaseStats, DerivedStats, NonCombatStats } from './types';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Character/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAOtC,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC5B;AAMD,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CAqB1E;AAED,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCharacter = createCharacter;
4
+ const Utils_1 = require("../Utils");
5
+ const game_mechanics_constants_1 = require("../Game/game-mechanics.constants");
6
+ function createCharacter(options) {
7
+ const { name, level, baseStats, inventory = [], effects = [] } = options;
8
+ const maxHealth = (0, Utils_1.calculateMaxHealth)(level, baseStats);
9
+ const maxMana = (0, Utils_1.calculateMaxMana)(level, baseStats);
10
+ return {
11
+ name,
12
+ level,
13
+ experience: (level - 1) * game_mechanics_constants_1.EXPERIENCE_PER_LEVEL,
14
+ experienceToNextLevel: level * game_mechanics_constants_1.EXPERIENCE_PER_LEVEL,
15
+ health: maxHealth,
16
+ maxHealth,
17
+ mana: maxMana,
18
+ maxMana,
19
+ baseStats,
20
+ derivedStats: (0, Utils_1.deriveStats)(baseStats),
21
+ nonCombatStats: (0, Utils_1.deriveNonCombatStats)(baseStats),
22
+ inventory,
23
+ effects,
24
+ };
25
+ }
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Character/index.ts"],"names":[],"mappings":";;AAqBA,0CAqBC;AAvCD,oCAAmG;AACnG,+EAAwE;AAiBxE,SAAgB,eAAe,CAAC,OAA+B;IAC3D,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAEzE,MAAM,SAAS,GAAG,IAAA,0BAAkB,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,IAAA,wBAAgB,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAEnD,OAAO;QACH,IAAI;QACJ,KAAK;QACL,UAAU,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,+CAAoB;QAC9C,qBAAqB,EAAE,KAAK,GAAG,+CAAoB;QACnD,MAAM,EAAE,SAAS;QACjB,SAAS;QACT,IAAI,EAAE,OAAO;QACb,OAAO;QACP,SAAS;QACT,YAAY,EAAE,IAAA,mBAAW,EAAC,SAAS,CAAC;QACpC,cAAc,EAAE,IAAA,4BAAoB,EAAC,SAAS,CAAC;QAC/C,SAAS;QACT,OAAO;KACV,CAAC;AACN,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { Stance, Advantage } from './types';
2
+ export declare function determineAdvantage(attacker: Stance, defender: Stance): Advantage;
3
+ export declare function hasAdvantage(attacker: Stance, defender: Stance): boolean;
4
+ export declare function getAdvantageModifier(advantage: Advantage): number;
5
+ //# sourceMappingURL=advantage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advantage.d.ts","sourceRoot":"","sources":["../../src/Combat/advantage.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAG5C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAMhF;AAGD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAExE;AAGD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAMjE"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.determineAdvantage = determineAdvantage;
4
+ exports.hasAdvantage = hasAdvantage;
5
+ exports.getAdvantageModifier = getAdvantageModifier;
6
+ function determineAdvantage(attacker, defender) {
7
+ if (attacker === defender)
8
+ return 'neutral';
9
+ if (attacker === 'heart' && defender === 'body')
10
+ return 'advantage';
11
+ if (attacker === 'body' && defender === 'mind')
12
+ return 'advantage';
13
+ if (attacker === 'mind' && defender === 'heart')
14
+ return 'advantage';
15
+ return 'disadvantage';
16
+ }
17
+ function hasAdvantage(attacker, defender) {
18
+ return determineAdvantage(attacker, defender) === 'advantage';
19
+ }
20
+ function getAdvantageModifier(advantage) {
21
+ switch (advantage) {
22
+ case 'advantage': return 2;
23
+ case 'disadvantage': return -2;
24
+ default: return 0;
25
+ }
26
+ }
27
+ //# sourceMappingURL=advantage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advantage.js","sourceRoot":"","sources":["../../src/Combat/advantage.ts"],"names":[],"mappings":";;AAOA,gDAMC;AAGD,oCAEC;AAGD,oDAMC;AApBD,SAAgB,kBAAkB,CAAC,QAAgB,EAAE,QAAgB;IACjE,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,WAAW,CAAC;IACpE,IAAI,QAAQ,KAAK,MAAM,IAAK,QAAQ,KAAK,MAAM;QAAE,OAAO,WAAW,CAAC;IACpE,IAAI,QAAQ,KAAK,MAAM,IAAK,QAAQ,KAAK,OAAO;QAAE,OAAO,WAAW,CAAC;IACrE,OAAO,cAAc,CAAC;AAC1B,CAAC;AAGD,SAAgB,YAAY,CAAC,QAAgB,EAAE,QAAgB;IAC3D,OAAO,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,WAAW,CAAC;AAClE,CAAC;AAGD,SAAgB,oBAAoB,CAAC,SAAoB;IACrD,QAAQ,SAAS,EAAE,CAAC;QAChB,KAAK,WAAW,CAAC,CAAI,OAAO,CAAC,CAAC;QAC9B,KAAK,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/B,OAAO,CAAC,CAAa,OAAO,CAAC,CAAC;IAClC,CAAC;AACL,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Character } from '../Character/types';
2
+ import { Enemy } from '../Enemy/types';
3
+ import { Stance, Action, CombatPhase, CombatState, BattleLogEntry } from './types';
4
+ export declare function initializeCombat(player: Character, enemy: Enemy): CombatState;
5
+ export declare function setPhase(state: CombatState, phase: CombatPhase): CombatState;
6
+ export declare function setPlayerStance(state: CombatState, stance: Stance): CombatState;
7
+ export declare function setPlayerAction(state: CombatState, action: Action): CombatState;
8
+ export declare function appendLog(state: CombatState, entry: BattleLogEntry): CombatState;
9
+ export declare function incrementFriendship(state: CombatState): CombatState;
10
+ export declare function endCombat(state: CombatState): CombatState;
11
+ export declare const updateCombatPhase: typeof setPhase;
12
+ export declare const addBattleLogEntry: typeof appendLog;
13
+ export declare const endCombatPlayerVictory: typeof endCombat;
14
+ export declare const endCombatPlayerDefeat: typeof endCombat;
15
+ export declare const endCombatWithFriendship: typeof endCombat;
16
+ //# sourceMappingURL=combat.reducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combat.reducer.d.ts","sourceRoot":"","sources":["../../src/Combat/combat.reducer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,OAAO,EACH,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAC3D,MAAM,SAAS,CAAC;AAMjB,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,WAAW,CAY7E;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,GAAG,WAAW,CAE5E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAE/E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAE/E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,GAAG,WAAW,CAEhF;AAGD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAEnE;AAGD,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAEzD;AAGD,eAAO,MAAM,iBAAiB,iBAAW,CAAC;AAC1C,eAAO,MAAM,iBAAiB,kBAAY,CAAC;AAC3C,eAAO,MAAM,sBAAsB,kBAAY,CAAC;AAChD,eAAO,MAAM,qBAAqB,kBAAY,CAAC;AAC/C,eAAO,MAAM,uBAAuB,kBAAY,CAAC"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.endCombatWithFriendship = exports.endCombatPlayerDefeat = exports.endCombatPlayerVictory = exports.addBattleLogEntry = exports.updateCombatPhase = void 0;
4
+ exports.initializeCombat = initializeCombat;
5
+ exports.setPhase = setPhase;
6
+ exports.setPlayerStance = setPlayerStance;
7
+ exports.setPlayerAction = setPlayerAction;
8
+ exports.appendLog = appendLog;
9
+ exports.incrementFriendship = incrementFriendship;
10
+ exports.endCombat = endCombat;
11
+ const Utils_1 = require("../Utils");
12
+ function initializeCombat(player, enemy) {
13
+ return {
14
+ active: true,
15
+ phase: 'choosing_stance',
16
+ round: 1,
17
+ friendshipCounter: 0,
18
+ player: (0, Utils_1.deepClone)(player),
19
+ enemy: (0, Utils_1.deepClone)(enemy),
20
+ playerChoice: {},
21
+ enemyChoice: {},
22
+ log: [],
23
+ };
24
+ }
25
+ function setPhase(state, phase) {
26
+ return { ...state, phase };
27
+ }
28
+ function setPlayerStance(state, stance) {
29
+ return { ...state, playerChoice: { ...state.playerChoice, stance } };
30
+ }
31
+ function setPlayerAction(state, action) {
32
+ return { ...state, playerChoice: { ...state.playerChoice, action } };
33
+ }
34
+ function appendLog(state, entry) {
35
+ return { ...state, log: [...state.log, entry] };
36
+ }
37
+ function incrementFriendship(state) {
38
+ return { ...state, friendshipCounter: state.friendshipCounter + 1 };
39
+ }
40
+ function endCombat(state) {
41
+ return { ...state, active: false, phase: 'ended' };
42
+ }
43
+ exports.updateCombatPhase = setPhase;
44
+ exports.addBattleLogEntry = appendLog;
45
+ exports.endCombatPlayerVictory = endCombat;
46
+ exports.endCombatPlayerDefeat = endCombat;
47
+ exports.endCombatWithFriendship = endCombat;
48
+ //# sourceMappingURL=combat.reducer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combat.reducer.js","sourceRoot":"","sources":["../../src/Combat/combat.reducer.ts"],"names":[],"mappings":";;;AAeA,4CAYC;AAED,4BAEC;AAED,0CAEC;AAED,0CAEC;AAED,8BAEC;AAGD,kDAEC;AAGD,8BAEC;AA/CD,oCAAqC;AASrC,SAAgB,gBAAgB,CAAC,MAAiB,EAAE,KAAY;IAC5D,OAAO;QACH,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,iBAAiB;QACxB,KAAK,EAAE,CAAC;QACR,iBAAiB,EAAE,CAAC;QACpB,MAAM,EAAE,IAAA,iBAAS,EAAC,MAAM,CAAC;QACzB,KAAK,EAAE,IAAA,iBAAS,EAAC,KAAK,CAAC;QACvB,YAAY,EAAE,EAAE;QAChB,WAAW,EAAE,EAAE;QACf,GAAG,EAAE,EAAE;KACV,CAAC;AACN,CAAC;AAED,SAAgB,QAAQ,CAAC,KAAkB,EAAE,KAAkB;IAC3D,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,SAAgB,eAAe,CAAC,KAAkB,EAAE,MAAc;IAC9D,OAAO,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,EAAE,GAAG,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC;AACzE,CAAC;AAED,SAAgB,eAAe,CAAC,KAAkB,EAAE,MAAc;IAC9D,OAAO,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,EAAE,GAAG,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC;AACzE,CAAC;AAED,SAAgB,SAAS,CAAC,KAAkB,EAAE,KAAqB;IAC/D,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;AACpD,CAAC;AAGD,SAAgB,mBAAmB,CAAC,KAAkB;IAClD,OAAO,EAAE,GAAG,KAAK,EAAE,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC;AACxE,CAAC;AAGD,SAAgB,SAAS,CAAC,KAAkB;IACxC,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACvD,CAAC;AAGY,QAAA,iBAAiB,GAAG,QAAQ,CAAC;AAC7B,QAAA,iBAAiB,GAAG,SAAS,CAAC;AAC9B,QAAA,sBAAsB,GAAG,SAAS,CAAC;AACnC,QAAA,qBAAqB,GAAG,SAAS,CAAC;AAClC,QAAA,uBAAuB,GAAG,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function applyCriticalMultiplier(baseDamage: number): number;
2
+ export declare function calculateFinalDamage(baseDamage: number, damageReduction: number, isCritical: boolean, damageBonus?: number): number;
3
+ export declare function isAttackSuccessful(attackRoll: number, defenseRoll: number): boolean;
4
+ //# sourceMappingURL=damage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"damage.d.ts","sourceRoot":"","sources":["../../src/Combat/damage.ts"],"names":[],"mappings":"AAMA,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAElE;AAUD,wBAAgB,oBAAoB,CAChC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,OAAO,EACnB,WAAW,SAAI,GAChB,MAAM,CAGR;AAGD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAEnF"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyCriticalMultiplier = applyCriticalMultiplier;
4
+ exports.calculateFinalDamage = calculateFinalDamage;
5
+ exports.isAttackSuccessful = isAttackSuccessful;
6
+ function applyCriticalMultiplier(baseDamage) {
7
+ return baseDamage * 2;
8
+ }
9
+ function calculateFinalDamage(baseDamage, damageReduction, isCritical, damageBonus = 0) {
10
+ const damage = isCritical ? applyCriticalMultiplier(baseDamage) : baseDamage;
11
+ return Math.ceil(Math.max(0, damage + damageBonus - damageReduction));
12
+ }
13
+ function isAttackSuccessful(attackRoll, defenseRoll) {
14
+ return attackRoll > defenseRoll;
15
+ }
16
+ //# sourceMappingURL=damage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"damage.js","sourceRoot":"","sources":["../../src/Combat/damage.ts"],"names":[],"mappings":";;AAMA,0DAEC;AAUD,oDAQC;AAGD,gDAEC;AAzBD,SAAgB,uBAAuB,CAAC,UAAkB;IACtD,OAAO,UAAU,GAAG,CAAC,CAAC;AAC1B,CAAC;AAUD,SAAgB,oBAAoB,CAChC,UAAkB,EAClB,eAAuB,EACvB,UAAmB,EACnB,WAAW,GAAG,CAAC;IAEf,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7E,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC;AAC1E,CAAC;AAGD,SAAgB,kBAAkB,CAAC,UAAkB,EAAE,WAAmB;IACtE,OAAO,UAAU,GAAG,WAAW,CAAC;AACpC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Advantage } from './types';
2
+ export declare function rollSkillCheck(modifier: number, advantage: Advantage): {
3
+ total: number;
4
+ roll: number;
5
+ modifier: number;
6
+ };
7
+ export declare function isCriticalHit(roll: number): boolean;
8
+ export declare function isCriticalMiss(roll: number): boolean;
9
+ //# sourceMappingURL=dice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dice.d.ts","sourceRoot":"","sources":["../../src/Combat/dice.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAOpC,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,GACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAGnD;AAGD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAwB;AAG5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAuB"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rollSkillCheck = rollSkillCheck;
4
+ exports.isCriticalHit = isCriticalHit;
5
+ exports.isCriticalMiss = isCriticalMiss;
6
+ const Utils_1 = require("../Utils");
7
+ function rollSkillCheck(modifier, advantage) {
8
+ const roll = (0, Utils_1.createDieRoll)(advantage)();
9
+ return { total: roll + modifier, roll, modifier };
10
+ }
11
+ function isCriticalHit(roll) { return roll === 20; }
12
+ function isCriticalMiss(roll) { return roll === 1; }
13
+ //# sourceMappingURL=dice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dice.js","sourceRoot":"","sources":["../../src/Combat/dice.ts"],"names":[],"mappings":";;AAYA,wCAMC;AAGD,sCAA4E;AAG5E,wCAA4E;AApB5E,oCAAyC;AAQzC,SAAgB,cAAc,CAC1B,QAAgB,EAChB,SAAoB;IAEpB,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,SAAS,CAAC,EAAE,CAAC;IACxC,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACtD,CAAC;AAGD,SAAgB,aAAa,CAAC,IAAY,IAAa,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;AAG5E,SAAgB,cAAc,CAAC,IAAY,IAAa,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { Character } from '../../Character/types';
2
+ import { Enemy } from '../../Enemy/types';
3
+ import { CombatAction, CombatState, Stance, Advantage } from '../types';
4
+ export declare function resolveAttackVsAttack(player: Character, enemy: Enemy, playerType: Stance, enemyType: Stance, playerAdv: Advantage, enemyAdv: Advantage): {
5
+ player: Character;
6
+ enemy: Enemy;
7
+ };
8
+ export declare function resolvePlayerAttackEnemyDefend(player: Character, enemy: Enemy, playerType: Stance, enemyType: Stance, playerAdv: Advantage, enemyAdv: Advantage): {
9
+ player: Character;
10
+ enemy: Enemy;
11
+ };
12
+ export declare function resolvePlayerDefendEnemyAttack(player: Character, enemy: Enemy, playerType: Stance, enemyType: Stance, playerAdv: Advantage, enemyAdv: Advantage): {
13
+ player: Character;
14
+ enemy: Enemy;
15
+ };
16
+ export declare function resolveCombatTurn(state: CombatState, playerAction: CombatAction, enemyAction: CombatAction): CombatState;
17
+ //# sourceMappingURL=combat.engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combat.engine.d.ts","sourceRoot":"","sources":["../../../src/Combat/e2e/combat.engine.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AA6BxE,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,SAAS,GACpB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CA+CrC;AAGD,wBAAgB,8BAA8B,CAC1C,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,SAAS,GACpB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAyBrC;AAGD,wBAAgB,8BAA8B,CAC1C,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,SAAS,GACpB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAsBrC;AAmBD,wBAAgB,iBAAiB,CAC7B,KAAK,EAAE,WAAW,EAClB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,YAAY,GAC1B,WAAW,CAqDb"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveAttackVsAttack = resolveAttackVsAttack;
4
+ exports.resolvePlayerAttackEnemyDefend = resolvePlayerAttackEnemyDefend;
5
+ exports.resolvePlayerDefendEnemyAttack = resolvePlayerDefendEnemyAttack;
6
+ exports.resolveCombatTurn = resolveCombatTurn;
7
+ const __1 = require("..");
8
+ const Utils_1 = require("../../Utils");
9
+ const game_mechanics_constants_1 = require("../../Game/game-mechanics.constants");
10
+ const Effects_1 = require("../../Effects");
11
+ function resolveAttackVsAttack(player, enemy, playerType, enemyType, playerAdv, enemyAdv) {
12
+ const playerDieRoll = (0, Utils_1.createDieRoll)(playerAdv);
13
+ const enemyDieRoll = (0, Utils_1.createDieRoll)(enemyAdv);
14
+ const pRollMod = (0, __1.getActiveRollModifier)(player);
15
+ const pBaseStat = (0, __1.getAttackStat)(player, playerType);
16
+ const pMod = pBaseStat + pRollMod;
17
+ const playerTotal = playerDieRoll() + pMod;
18
+ const eRollMod = (0, __1.getActiveRollModifier)(enemy);
19
+ const eBaseStat = (0, __1.getAttackStat)(enemy, enemyType);
20
+ const eMod = eBaseStat + eRollMod;
21
+ const enemyTotal = enemyDieRoll() + eMod;
22
+ if (playerTotal > enemyTotal) {
23
+ const baseDefense = (0, __1.getDefenseStat)(enemy, enemyType);
24
+ const studyBonus = playerType === 'mind' ? (0, __1.getStudyMarkIntensity)(enemy) : 0;
25
+ const damageRoll = playerDieRoll() + pMod;
26
+ const finalDamage = (0, __1.calculateFinalDamage)(damageRoll, baseDefense * game_mechanics_constants_1.PASSIVE_DEFENSE_MULTIPLIER, false, studyBonus);
27
+ let updatedEnemy = (0, __1.applyDamage)(enemy, finalDamage);
28
+ let updatedPlayer = player;
29
+ if (playerType === 'heart') {
30
+ updatedEnemy = (0, __1.removeRandomBuff)(updatedEnemy).target;
31
+ updatedPlayer = (0, __1.extendRandomBuffDuration)(updatedPlayer, 1).target;
32
+ }
33
+ return { player: updatedPlayer, enemy: updatedEnemy };
34
+ }
35
+ if (enemyTotal > playerTotal) {
36
+ const baseDefense = (0, __1.getBaseStat)(player, playerType);
37
+ const studyBonus = enemyType === 'mind' ? (0, __1.getStudyMarkIntensity)(player) : 0;
38
+ const damageRoll = enemyDieRoll() + eMod;
39
+ const finalDamage = (0, __1.calculateFinalDamage)(damageRoll, baseDefense * game_mechanics_constants_1.PASSIVE_DEFENSE_MULTIPLIER, false, studyBonus);
40
+ const updatedPlayer = (0, __1.applyDamage)(player, finalDamage);
41
+ let updatedEnemy = enemy;
42
+ const thorns = (0, __1.getThornsReflect)(updatedPlayer);
43
+ if (thorns > 0)
44
+ updatedEnemy = (0, __1.applyDamage)(updatedEnemy, thorns);
45
+ return { player: updatedPlayer, enemy: updatedEnemy };
46
+ }
47
+ return { player, enemy };
48
+ }
49
+ function resolvePlayerAttackEnemyDefend(player, enemy, playerType, enemyType, playerAdv, enemyAdv) {
50
+ const playerDieRoll = (0, Utils_1.createDieRoll)(playerAdv);
51
+ const pRollMod = (0, __1.getActiveRollModifier)(player);
52
+ const pBaseStat = (0, __1.getAttackStat)(player, playerType);
53
+ const attackMod = pBaseStat + pRollMod;
54
+ playerDieRoll();
55
+ const damageRoll = playerDieRoll() + attackMod;
56
+ const baseDefense = (0, __1.getDefenseStat)(enemy, enemyType);
57
+ const defenseMultiplier = game_mechanics_constants_1.DEFENSE_MULTIPLIERS[enemyAdv];
58
+ const studyBonus = playerType === 'mind' ? (0, __1.getStudyMarkIntensity)(enemy) : 0;
59
+ const finalDamage = (0, __1.calculateFinalDamage)(damageRoll, baseDefense * defenseMultiplier, false, studyBonus);
60
+ let updatedEnemy = (0, __1.applyDamage)(enemy, finalDamage);
61
+ let updatedPlayer = player;
62
+ if (playerType === 'heart') {
63
+ updatedEnemy = (0, __1.removeRandomBuff)(updatedEnemy).target;
64
+ updatedPlayer = (0, __1.extendRandomBuffDuration)(updatedPlayer, 1).target;
65
+ }
66
+ return { player: updatedPlayer, enemy: updatedEnemy };
67
+ }
68
+ function resolvePlayerDefendEnemyAttack(player, enemy, playerType, enemyType, playerAdv, enemyAdv) {
69
+ const enemyDieRoll = (0, Utils_1.createDieRoll)(enemyAdv);
70
+ const eRollMod = (0, __1.getActiveRollModifier)(enemy);
71
+ const eBaseStat = (0, __1.getAttackStat)(enemy, enemyType);
72
+ const attackMod = eBaseStat + eRollMod;
73
+ enemyDieRoll();
74
+ const damageRoll = enemyDieRoll() + attackMod;
75
+ const baseDefense = (0, __1.getBaseStat)(player, playerType);
76
+ const defenseMultiplier = game_mechanics_constants_1.DEFENSE_MULTIPLIERS[playerAdv];
77
+ const studyBonus = enemyType === 'mind' ? (0, __1.getStudyMarkIntensity)(player) : 0;
78
+ const finalDamage = (0, __1.calculateFinalDamage)(damageRoll, baseDefense * defenseMultiplier, false, studyBonus);
79
+ const updatedPlayer = (0, __1.applyDamage)(player, finalDamage);
80
+ let updatedEnemy = enemy;
81
+ const thorns = (0, __1.getThornsReflect)(updatedPlayer);
82
+ if (thorns > 0)
83
+ updatedEnemy = (0, __1.applyDamage)(updatedEnemy, thorns);
84
+ return { player: updatedPlayer, enemy: updatedEnemy };
85
+ }
86
+ function resolveCombatTurn(state, playerAction, enemyAction) {
87
+ let player = state.player;
88
+ let enemy = state.enemy;
89
+ player = (0, __1.applyRegen)(player).target;
90
+ enemy = (0, __1.applyRegen)(enemy).target;
91
+ player = { ...player, effects: (0, Effects_1.clearTier1EffectsForStance)(player.effects, playerAction.stance).activeEffects };
92
+ enemy = { ...enemy, effects: (0, Effects_1.clearTier1EffectsForStance)(enemy.effects, enemyAction.stance).activeEffects };
93
+ const playerAdvantage = (0, __1.determineAdvantage)(playerAction.stance, enemyAction.stance);
94
+ const enemyAdvantage = (0, __1.determineAdvantage)(enemyAction.stance, playerAction.stance);
95
+ const playerTier1 = (0, Effects_1.applyTier1CombatEffect)(player.effects, enemy.effects, playerAction, state.round);
96
+ player = { ...player, effects: playerTier1.actorEffects };
97
+ enemy = { ...enemy, effects: playerTier1.opponentEffects };
98
+ const enemyTier1 = (0, Effects_1.applyTier1CombatEffect)(enemy.effects, player.effects, enemyAction, state.round, state.enemy.tier1Overrides);
99
+ enemy = { ...enemy, effects: enemyTier1.actorEffects };
100
+ player = { ...player, effects: enemyTier1.opponentEffects };
101
+ let friendshipCounter = state.friendshipCounter;
102
+ if (playerAction.action === 'attack' && enemyAction.action === 'attack') {
103
+ ({ player, enemy } = resolveAttackVsAttack(player, enemy, playerAction.stance, enemyAction.stance, playerAdvantage, enemyAdvantage));
104
+ }
105
+ else if (playerAction.action === 'attack' && enemyAction.action === 'defend') {
106
+ ({ player, enemy } = resolvePlayerAttackEnemyDefend(player, enemy, playerAction.stance, enemyAction.stance, playerAdvantage, enemyAdvantage));
107
+ }
108
+ else if (playerAction.action === 'defend' && enemyAction.action === 'attack') {
109
+ ({ player, enemy } = resolvePlayerDefendEnemyAttack(player, enemy, playerAction.stance, enemyAction.stance, playerAdvantage, enemyAdvantage));
110
+ }
111
+ else {
112
+ friendshipCounter++;
113
+ }
114
+ player = (0, __1.tickAllEffects)(player).target;
115
+ enemy = (0, __1.tickAllEffects)(enemy).target;
116
+ return { ...state, player, enemy, friendshipCounter, round: state.round + 1 };
117
+ }
118
+ //# sourceMappingURL=combat.engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combat.engine.js","sourceRoot":"","sources":["../../../src/Combat/e2e/combat.engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { ActiveEffect } from '../Effects/types';
2
+ import { Combatant } from './types';
3
+ export declare const MIND_MARK_ID = "tier1_mind_mark";
4
+ export declare function getStudyMarkIntensity(target: Combatant): number;
5
+ export declare function getActiveRollModifier(target: Combatant): number;
6
+ export declare function getThornsReflect(bearer: Combatant): number;
7
+ export declare function updateEffectDuration<T extends Combatant>(target: T, effectId: string): T;
8
+ export declare function tickAllEffects<T extends Combatant>(target: T): {
9
+ target: T;
10
+ expired: ActiveEffect[];
11
+ };
12
+ export declare function removeRandomBuff<T extends Combatant>(target: T): {
13
+ target: T;
14
+ removed: ActiveEffect | null;
15
+ };
16
+ export declare function extendRandomBuffDuration<T extends Combatant>(target: T, amount: number): {
17
+ target: T;
18
+ extended: ActiveEffect | null;
19
+ };
20
+ export declare function applyRegen<T extends Combatant>(target: T): {
21
+ target: T;
22
+ healed: number;
23
+ };
24
+ //# sourceMappingURL=effects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effects.d.ts","sourceRoot":"","sources":["../../src/Combat/effects.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIpC,eAAO,MAAM,YAAY,oBAAoB,CAAC;AAG9C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAG/D;AAMD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAO/D;AAMD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAM1D;AAOD,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,CAOxF;AAOD,wBAAgB,cAAc,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAiBrG;AAMD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE,CAO5G;AAMD,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,SAAS,EACxD,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,GACf;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE,CAW9C;AAMD,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAcxF"}