@provable-games/dm-engine 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 (89) hide show
  1. package/dist/actions.d.ts +18 -0
  2. package/dist/actions.d.ts.map +1 -0
  3. package/dist/actions.js +88 -0
  4. package/dist/actions.js.map +1 -0
  5. package/dist/constants/beast.d.ts +28 -0
  6. package/dist/constants/beast.d.ts.map +1 -0
  7. package/dist/constants/beast.js +216 -0
  8. package/dist/constants/beast.js.map +1 -0
  9. package/dist/constants/game.d.ts +23 -0
  10. package/dist/constants/game.d.ts.map +1 -0
  11. package/dist/constants/game.js +26 -0
  12. package/dist/constants/game.js.map +1 -0
  13. package/dist/constants/loot.d.ts +341 -0
  14. package/dist/constants/loot.d.ts.map +1 -0
  15. package/dist/constants/loot.js +456 -0
  16. package/dist/constants/loot.js.map +1 -0
  17. package/dist/constants/obstacle.d.ts +4 -0
  18. package/dist/constants/obstacle.d.ts.map +1 -0
  19. package/dist/constants/obstacle.js +81 -0
  20. package/dist/constants/obstacle.js.map +1 -0
  21. package/dist/events.d.ts +50 -0
  22. package/dist/events.d.ts.map +1 -0
  23. package/dist/events.js +2 -0
  24. package/dist/events.js.map +1 -0
  25. package/dist/index.d.ts +30 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +34 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/packing.d.ts +6 -0
  30. package/dist/packing.d.ts.map +1 -0
  31. package/dist/packing.js +76 -0
  32. package/dist/packing.js.map +1 -0
  33. package/dist/protocol.d.ts +55 -0
  34. package/dist/protocol.d.ts.map +1 -0
  35. package/dist/protocol.js +250 -0
  36. package/dist/protocol.js.map +1 -0
  37. package/dist/replay.d.ts +35 -0
  38. package/dist/replay.d.ts.map +1 -0
  39. package/dist/replay.js +856 -0
  40. package/dist/replay.js.map +1 -0
  41. package/dist/rules/beast.d.ts +264 -0
  42. package/dist/rules/beast.d.ts.map +1 -0
  43. package/dist/rules/beast.js +535 -0
  44. package/dist/rules/beast.js.map +1 -0
  45. package/dist/rules/game.d.ts +35 -0
  46. package/dist/rules/game.d.ts.map +1 -0
  47. package/dist/rules/game.js +462 -0
  48. package/dist/rules/game.js.map +1 -0
  49. package/dist/rules/gameSimulation.d.ts +158 -0
  50. package/dist/rules/gameSimulation.d.ts.map +1 -0
  51. package/dist/rules/gameSimulation.js +845 -0
  52. package/dist/rules/gameSimulation.js.map +1 -0
  53. package/dist/rules/health.d.ts +3 -0
  54. package/dist/rules/health.d.ts.map +1 -0
  55. package/dist/rules/health.js +7 -0
  56. package/dist/rules/health.js.map +1 -0
  57. package/dist/rules/loot.d.ts +100 -0
  58. package/dist/rules/loot.d.ts.map +1 -0
  59. package/dist/rules/loot.js +626 -0
  60. package/dist/rules/loot.js.map +1 -0
  61. package/dist/rules/market.d.ts +28 -0
  62. package/dist/rules/market.d.ts.map +1 -0
  63. package/dist/rules/market.js +83 -0
  64. package/dist/rules/market.js.map +1 -0
  65. package/dist/rules/processFutures.d.ts +79 -0
  66. package/dist/rules/processFutures.d.ts.map +1 -0
  67. package/dist/rules/processFutures.js +429 -0
  68. package/dist/rules/processFutures.js.map +1 -0
  69. package/dist/rules/tokenId.d.ts +31 -0
  70. package/dist/rules/tokenId.d.ts.map +1 -0
  71. package/dist/rules/tokenId.js +102 -0
  72. package/dist/rules/tokenId.js.map +1 -0
  73. package/dist/staging.d.ts +18 -0
  74. package/dist/staging.d.ts.map +1 -0
  75. package/dist/staging.js +27 -0
  76. package/dist/staging.js.map +1 -0
  77. package/dist/transcript.d.ts +64 -0
  78. package/dist/transcript.d.ts.map +1 -0
  79. package/dist/transcript.js +92 -0
  80. package/dist/transcript.js.map +1 -0
  81. package/dist/types.d.ts +141 -0
  82. package/dist/types.d.ts.map +1 -0
  83. package/dist/types.js +2 -0
  84. package/dist/types.js.map +1 -0
  85. package/dist/view.d.ts +4 -0
  86. package/dist/view.d.ts.map +1 -0
  87. package/dist/view.js +18 -0
  88. package/dist/view.js.map +1 -0
  89. package/package.json +51 -0
@@ -0,0 +1,535 @@
1
+ import * as starknet from "@scure/starknet";
2
+ import { BEAST_NAME_PREFIXES, BEAST_NAME_SUFFIXES, BEAST_NAMES, BEAST_SPECIAL_NAME_LEVEL_UNLOCK, } from "../constants/beast.js";
3
+ import { unpackMintedBy } from "./tokenId.js";
4
+ export const beastTypeIcons = {
5
+ Brute: "/images/types/brute.svg",
6
+ Hunter: "/images/types/hunter.svg",
7
+ Magic: "/images/types/magic.svg",
8
+ };
9
+ /**
10
+ * Determines the beast type based on its ID
11
+ * @param id Beast ID
12
+ * @returns The type of the beast (Magic_or_Cloth, Blade_or_Hide, or Bludgeon_or_Metal)
13
+ */
14
+ export function getBeastType(id) {
15
+ if (id >= 0 && id < 26) {
16
+ return "Magic";
17
+ }
18
+ else if (id < 51) {
19
+ return "Hunter";
20
+ }
21
+ else if (id < 76) {
22
+ return "Brute";
23
+ }
24
+ else {
25
+ return "None";
26
+ }
27
+ }
28
+ /**
29
+ * Determines the attack type based on its ID
30
+ * @param id Attack ID
31
+ * @returns The type of the attack (Magic, Hunter, or Brute)
32
+ */
33
+ export function getAttackType(id) {
34
+ if (id >= 0 && id < 26) {
35
+ return "Magic";
36
+ }
37
+ else if (id < 51) {
38
+ return "Blade";
39
+ }
40
+ else if (id < 76) {
41
+ return "Bludgeon";
42
+ }
43
+ else {
44
+ return "None";
45
+ }
46
+ }
47
+ /**
48
+ * Determines the armor type based on its ID
49
+ * @param id Armor ID
50
+ * @returns The type of the armor (Cloth, Hide, or Metal)
51
+ */
52
+ export function getArmorType(id) {
53
+ if (id >= 0 && id < 26) {
54
+ return "Cloth";
55
+ }
56
+ else if (id < 51) {
57
+ return "Hide";
58
+ }
59
+ else if (id < 76) {
60
+ return "Metal";
61
+ }
62
+ else {
63
+ return "None";
64
+ }
65
+ }
66
+ /**
67
+ * Determines the beast tier based on its ID
68
+ * @param id Beast ID
69
+ * @returns The tier of the beast (T1-T5)
70
+ */
71
+ export function getBeastTier(id) {
72
+ if (isT1(id))
73
+ return 1;
74
+ if (isT2(id))
75
+ return 2;
76
+ if (isT3(id))
77
+ return 3;
78
+ if (isT4(id))
79
+ return 4;
80
+ return 5;
81
+ }
82
+ // Helper functions from beast.cairo
83
+ function isT1(id) {
84
+ return (id >= 1 && id <= 5) || (id >= 26 && id < 31) || (id >= 51 && id < 56);
85
+ }
86
+ function isT2(id) {
87
+ return (id >= 6 && id < 11) || (id >= 31 && id < 36) || (id >= 56 && id < 61);
88
+ }
89
+ function isT3(id) {
90
+ return (id >= 11 && id < 16) || (id >= 36 && id < 41) || (id >= 61 && id < 66);
91
+ }
92
+ function isT4(id) {
93
+ return (id >= 16 && id < 21) || (id >= 41 && id < 46) || (id >= 66 && id < 71);
94
+ }
95
+ /**
96
+ * The "wanted beast" bounty (Raid Boss dungeon): the T1 Magicals — beast ids 1..5
97
+ * (Warlock, Typhon, Jiangshi, Anansi, Basilisk). Mirrors multi_community.cairo's
98
+ * WANTED_BEAST_ID_MIN/MAX.
99
+ */
100
+ export const WANTED_BEAST_IDS = [1, 2, 3, 4, 5];
101
+ /**
102
+ * Whether a beast qualifies for the Raid Boss wanted-beast bounty: a T1 Magical
103
+ * (id 1..5) at level >= 19 — the level at which the combat system writes the
104
+ * on-chain collectable the bounty pays out against. This is gated on the beast's
105
+ * LEVEL directly (not the `isCollectable` flag, which is dungeon-gated by
106
+ * `collectableBeasts` and is false in Raid Boss). The dungeon (raid_boss) and
107
+ * prizes-remaining checks are layered on at the call site.
108
+ */
109
+ export function isWantedBeast(beast) {
110
+ return beast.id >= 1 && beast.id <= 5 && beast.level >= BEAST_SPECIAL_NAME_LEVEL_UNLOCK;
111
+ }
112
+ /**
113
+ * Asset basename for the wanted beast ("Mummy") — used for both the portrait
114
+ * (`/images/beasts/${WANTED_BEAST_ASSET}.png`) and the battle scene
115
+ * (`/images/battle_scenes/${WANTED_BEAST_ASSET}.png`).
116
+ */
117
+ export const WANTED_BEAST_ASSET = "mummy";
118
+ /** Base display name for a wanted beast (like the Ducky dungeon reskins beast 1 → Ducky). */
119
+ export const WANTED_BEAST_NAME = "Mummy";
120
+ /**
121
+ * Display name for a wanted beast. Unlike the previous Gigaverse reskin (which replaced the whole
122
+ * name), the Mummy keeps its NORMAL special prefix/suffix — only the base name is swapped, so a
123
+ * level-19+ Warlock with specials reads `"Agony Bane" Mummy`. Same quoting as `getBeastName`.
124
+ */
125
+ export function getWantedBeastName(beast) {
126
+ return nameWithSpecials(WANTED_BEAST_NAME, beast.specialPrefix, beast.specialSuffix);
127
+ }
128
+ /**
129
+ * Loot's quoting for a named beast: `"Agony Bane" Mummy`, or just the base name
130
+ * when it has no specials. The one place the format lives — `getBeastName`
131
+ * (stock beasts), `getWantedBeastName` (the bounty Mummy) and the Black Shuck
132
+ * reskin all render through it, so a reskinned beast reads the same way as the
133
+ * beast it replaced.
134
+ */
135
+ export function nameWithSpecials(baseName, prefix, suffix) {
136
+ if (prefix && suffix) {
137
+ return `"${prefix} ${suffix}" ${baseName}`;
138
+ }
139
+ else if (prefix) {
140
+ return `"${prefix}" ${baseName}`;
141
+ }
142
+ else if (suffix) {
143
+ return `"${suffix}" ${baseName}`;
144
+ }
145
+ return baseName;
146
+ }
147
+ /** Custom wanted-beast portrait/sprite image ("Mummy"). */
148
+ export const getWantedBeastImageById = (_id) => {
149
+ return `/images/beasts/${WANTED_BEAST_ASSET}.png`;
150
+ };
151
+ /**
152
+ * Reverse the display prefix/suffix back to the on-chain special ids the contract hashes.
153
+ * Returns 0 for an absent special, matching how a sub-level-19 beast is encoded.
154
+ */
155
+ export function getBeastSpecialIds(beast) {
156
+ const prefixKey = beast.specialPrefix
157
+ ? Object.keys(BEAST_NAME_PREFIXES).find((key) => BEAST_NAME_PREFIXES[parseInt(key)] === beast.specialPrefix)
158
+ : undefined;
159
+ const suffixKey = beast.specialSuffix
160
+ ? Object.keys(BEAST_NAME_SUFFIXES).find((key) => BEAST_NAME_SUFFIXES[parseInt(key)] === beast.specialSuffix)
161
+ : undefined;
162
+ return {
163
+ prefix: prefixKey ? parseInt(prefixKey) : 0,
164
+ suffix: suffixKey ? parseInt(suffixKey) : 0,
165
+ };
166
+ }
167
+ /**
168
+ * Identity of a wanted-beast ENCOUNTER for the client's per-encounter latch. Includes the specials
169
+ * because the bounty is per (beast, prefix, suffix): two same-level Warlocks with different specials
170
+ * are distinct collectables with distinct claims.
171
+ */
172
+ export function wantedEncounterKey(beast) {
173
+ return `${beast.id}:${beast.level}:${beast.specialPrefix ?? ""}:${beast.specialSuffix ?? ""}`;
174
+ }
175
+ /**
176
+ * The on-chain collectable id for a beast kill, mirroring combat.cairo and the dungeon's
177
+ * `claim_prize`: poseidon(minted_by, poseidon(beast_id, prefix, suffix)).
178
+ *
179
+ * NOTE `minted_by` is the DUNGEON's minter id (packed into every token it mints), NOT anything
180
+ * per-adventurer — so this id is shared by every player in the dungeon who meets the same
181
+ * (beast, prefix, suffix). That collision is exactly what makes the bounty first-come-first-served:
182
+ * once a combo's collectable is claimed, no one else can ever claim it.
183
+ */
184
+ export function getCollectableId(gameId, beast) {
185
+ const { prefix, suffix } = getBeastSpecialIds(beast);
186
+ const beastHash = starknet.poseidonHashMany([BigInt(beast.id), BigInt(prefix), BigInt(suffix)]);
187
+ return starknet.poseidonHashMany([BigInt(unpackMintedBy(gameId)), beastHash]);
188
+ }
189
+ /**
190
+ * Composes a beast's display name from an arbitrary base name plus its specials.
191
+ *
192
+ * The base name is a parameter rather than a lookup because a themed dungeon
193
+ * (@/config/themes) renders the same beast id under a different species, and the
194
+ * wanted-beast Mummy swaps the species while keeping the real prefix/suffix.
195
+ * Every one of those cases is this same quoting rule over a different base.
196
+ *
197
+ * `hideSpecials` drops the quoted segment entirely (a theme setting). It is
198
+ * presentation only -- callers keep the prefix/suffix strings on the beast,
199
+ * because they are reverse-mapped back to on-chain ids for collectable claims.
200
+ *
201
+ * @param baseName The species to render
202
+ * @param level Beast level -- specials only exist from BEAST_SPECIAL_NAME_LEVEL_UNLOCK
203
+ * @param special2 Special prefix index
204
+ * @param special3 Special suffix index
205
+ */
206
+ export function composeBeastName(baseName, level, special2, special3, hideSpecials = false) {
207
+ if (hideSpecials) {
208
+ return baseName;
209
+ }
210
+ // Get special name components if level requirement is met
211
+ const specialPrefix = level >= BEAST_SPECIAL_NAME_LEVEL_UNLOCK ? BEAST_NAME_PREFIXES[special2] : undefined;
212
+ const specialSuffix = level >= BEAST_SPECIAL_NAME_LEVEL_UNLOCK ? BEAST_NAME_SUFFIXES[special3] : undefined;
213
+ // `nameWithSpecials` (above) is the one place the quoting rule lives.
214
+ return nameWithSpecials(baseName, specialPrefix, specialSuffix);
215
+ }
216
+ /**
217
+ * Gets the name of a beast based on its ID and special attributes
218
+ * @param id Beast ID (1-75)
219
+ * @param level Beast level
220
+ * @param special2 Special prefix index
221
+ * @param special3 Special suffix index
222
+ * @returns The name of the beast, including special prefix/suffix if applicable
223
+ */
224
+ export function getBeastName(id, level, special2, special3) {
225
+ // Same level-gating and quoting as any themed beast, so keep the one helper.
226
+ return composeBeastName(BEAST_NAMES[id], level, special2, special3);
227
+ }
228
+ /**
229
+ * The Black Shuck Festival dungeon id, as keyed in DUNGEON_CONFIGS. Lives here
230
+ * rather than being imported from `@/config/dungeons` because that module
231
+ * imports this one (dungeon overviews pull in beast helpers) — a direct import
232
+ * would close the cycle.
233
+ */
234
+ export const BLACK_SHUCK_DUNGEON_ID = "black-shuck-festival";
235
+ /**
236
+ * The Black Shuck bounty: the T1 Hunters — beast ids 26..30 (Griffin,
237
+ * Manticore, Phoenix, Dragon, Minotaur). Mirrors black_shuck.cairo's
238
+ * T1_HUNTER_MIN/MAX, which is the range `claim_reward` asserts on; a kill
239
+ * outside it reverts with 'Not a T1 hunter'.
240
+ */
241
+ export const BLACK_SHUCK_BEAST_IDS = [26, 27, 28, 29, 30];
242
+ /**
243
+ * Display name and asset key for the Black Shuck. Unlike the Karat, the
244
+ * collectible the dungeon mints IS a beast — it inherits the slain hunter's
245
+ * level, health, prefix/suffix and shiny/animated traits, and only the species
246
+ * is fixed. So the encounter presents as the hound itself rather than as a
247
+ * separate reward object.
248
+ */
249
+ export const BLACK_SHUCK_NAME = "Black Shuck";
250
+ /**
251
+ * Whether a beast qualifies for the Black Shuck reward: a T1 Hunter that the
252
+ * combat system flagged collectable. The level floor is implied by
253
+ * `isCollectable` (the contract needs the on-chain collectable record to exist
254
+ * before `claim_reward` will pay), but it is checked explicitly here so the
255
+ * override and the claim gate agree with `getCollectableBeastOverride`.
256
+ */
257
+ export function isBlackShuckBeast(beast) {
258
+ return (BLACK_SHUCK_BEAST_IDS.includes(beast.id) &&
259
+ beast.level >= BEAST_SPECIAL_NAME_LEVEL_UNLOCK &&
260
+ !!beast.isCollectable);
261
+ }
262
+ /**
263
+ * Beast ids whose collectable, special-level kill unlocks a Karat: Warlock (1)
264
+ * and Typhon (2). Two eligible beasts ≈ 2× the odds of a qualifying collectable
265
+ * per run vs. a single id. Mirrors REWARD_BEAST_ID_{1,2} in karat.cairo — keep
266
+ * in sync with the deployed contract's `claim_reward` gate.
267
+ */
268
+ export const KARAT_COLLECTABLE_BEAST_IDS = [1, 2];
269
+ /**
270
+ * Display name and asset key for the Karats-dungeon collectable encounter. The
271
+ * dungeon's prize is a Karat Gen2 NFT rather than a beast, so what you fight is
272
+ * the Carbuncle that guards it: the name keys its own art
273
+ * (`/images/battle_scenes/carbuncle.png`) and its intro stream, while the
274
+ * portrait stays the gem (see `karatActive`).
275
+ */
276
+ export const CARBUNCLE_NAME = "Carbuncle";
277
+ /**
278
+ * Whether a beast is the Karats-dungeon reward encounter: a collectable
279
+ * special-level Warlock or Typhon. Mirrors the karats branch of
280
+ * `getCollectableBeastOverride` — the reskin and the claim gate must agree —
281
+ * and `REWARD_BEAST_ID_{1,2}` in karat.cairo, which `claim_reward` asserts on.
282
+ */
283
+ export function isCarbuncleBeast(beast) {
284
+ return (KARAT_COLLECTABLE_BEAST_IDS.includes(beast.id) &&
285
+ beast.level >= BEAST_SPECIAL_NAME_LEVEL_UNLOCK &&
286
+ !!beast.isCollectable);
287
+ }
288
+ /**
289
+ * Dungeon-specific collectable reskin: in the Ducky dungeon, a collectable
290
+ * special-level beast id 1 presents as the Ducky; in the Karats dungeon a
291
+ * collectable special-level Warlock (id 1) OR Typhon (id 2) presents as the
292
+ * Karat (the gem you'd claim); in the Black Shuck Festival any collectable
293
+ * special-level T1 Hunter (26..30) presents as the Black Shuck. Single source
294
+ * of truth for both the event transformer and the on-chain beast-identity
295
+ * fallback — the returned `baseName` drives the battle scene
296
+ * (`/images/battle_scenes/${baseName}.png`) and the portrait.
297
+ *
298
+ * PREDATES the theme system (@/config/themes) and is deliberately kept separate
299
+ * from it: these three dungeons are live and their reskins gate real on-chain
300
+ * claims, so they keep the exact code path they have always had. `resolveBeast`
301
+ * applies this FIRST and themes second — themes are for new dungeons.
302
+ *
303
+ * `special2`/`special3` are the beast's raw special ids, and only the Black
304
+ * Shuck uses them: the hound IS the beast (it inherits the slain hunter's
305
+ * level, health and specials on mint), so it is named like one —
306
+ * `"Damnation Shout" Black Shuck`, the same shape the Mummy takes. The Ducky
307
+ * and the Karat are separate objects the beast merely stands in for, so they
308
+ * keep their own flat names. Omitting them just yields the bare base name.
309
+ */
310
+ export function getCollectableBeastOverride(dungeonId, beastId, level, isCollectable, special2, special3) {
311
+ if (level < BEAST_SPECIAL_NAME_LEVEL_UNLOCK || !isCollectable) {
312
+ return null;
313
+ }
314
+ if (dungeonId === "ducky" && beastId === 1) {
315
+ return { name: "Lil Loot Survivor Ducky", baseName: "Ducky" };
316
+ }
317
+ if (dungeonId === "karats" && KARAT_COLLECTABLE_BEAST_IDS.includes(beastId)) {
318
+ // The encounter is the Carbuncle that guards the gem, so it is named like a
319
+ // beast — specials and all, the same shape the Mummy and the hound take —
320
+ // and `baseName` keys its own art. The karat itself is a separate object,
321
+ // and shows up as the reward portrait rather than as the beast. Warlock (1)
322
+ // and Typhon (2) both qualify.
323
+ return {
324
+ name: nameWithSpecials(CARBUNCLE_NAME, BEAST_NAME_PREFIXES[special2], BEAST_NAME_SUFFIXES[special3]),
325
+ baseName: CARBUNCLE_NAME,
326
+ };
327
+ }
328
+ if (dungeonId === BLACK_SHUCK_DUNGEON_ID && BLACK_SHUCK_BEAST_IDS.includes(beastId)) {
329
+ // All five T1 Hunters collapse to the one hound, the way Gigaverse's five
330
+ // T1 Brutes collapse to the Hand of Bekda. `baseName` carries a space, so
331
+ // every asset lookup off it must underscore-normalise (see beastAssetKey).
332
+ return {
333
+ name: nameWithSpecials(BLACK_SHUCK_NAME, BEAST_NAME_PREFIXES[special2], BEAST_NAME_SUFFIXES[special3]),
334
+ baseName: BLACK_SHUCK_NAME,
335
+ };
336
+ }
337
+ return null;
338
+ }
339
+ /**
340
+ * Filename key for a beast's art, derived from its `baseName`. Every stock
341
+ * beast name is a single word, so this was historically just `.toLowerCase()`;
342
+ * the Black Shuck is the first `baseName` with a space in it, and its assets
343
+ * ship as `black_shuck.png` to match the rest of the directory's convention
344
+ * (and `getBeastImage`, which has always underscored).
345
+ */
346
+ export const beastAssetKey = (baseName) => baseName.toLowerCase().replace(/\s+/g, "_");
347
+ /**
348
+ * The 31 Karat Gen2 reward token ids in ON-CHAIN registration order
349
+ * (add_reward_tokens) — claims pay them out front to back, so the NEXT karat
350
+ * to be won is KARAT_REWARD_IDS[distributed] = ids[31 - rewards_remaining].
351
+ * Art is the token's on-chain SVG, snapshotted to /images/karats.
352
+ */
353
+ export const KARAT_REWARD_IDS = [
354
+ 143, 144, 145, 164, 165, 167, 168, 170, 173, 175, 182, 183, 184, 185, 186, 211, 213, 214, 215,
355
+ 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
356
+ ];
357
+ export const karatImagePath = (id) => `/images/karats/${id}.svg`;
358
+ /** The next-claimable karat's token id given the dungeon's rewards_remaining
359
+ * (rewards pay out in registration order; falls back to the first reward while
360
+ * the live count is unknown). */
361
+ export const nextKaratId = (rewardsRemaining) => {
362
+ const total = KARAT_REWARD_IDS.length;
363
+ const idx = rewardsRemaining == null ? 0 : Math.min(Math.max(total - rewardsRemaining, 0), total - 1);
364
+ return KARAT_REWARD_IDS[idx];
365
+ };
366
+ /** The next-claimable karat's art given the dungeon's rewards_remaining. */
367
+ export const nextKaratImage = (rewardsRemaining) => karatImagePath(nextKaratId(rewardsRemaining));
368
+ export const getBeastImage = (name) => {
369
+ return `/images/beasts/${beastAssetKey(name)}.png`;
370
+ };
371
+ export const getBeastImageById = (id) => {
372
+ return getBeastImage(BEAST_NAMES[id]);
373
+ };
374
+ export const getTierGlowColor = (tier) => {
375
+ switch (tier) {
376
+ case "1":
377
+ return "rgba(255, 0, 0, 0.5)"; // Red glow for T1
378
+ case "2":
379
+ return "rgba(255, 165, 0, 0.5)"; // Orange glow for T2
380
+ case "3":
381
+ return "rgba(255, 255, 0, 0.5)"; // Yellow glow for T3
382
+ case "4":
383
+ return "rgba(0, 255, 0, 0.5)"; // Green glow for T4
384
+ case "5":
385
+ return "rgba(0, 0, 255, 0.5)"; // Blue glow for T5
386
+ default:
387
+ return "rgba(128, 128, 128, 0.5)"; // Default gray glow
388
+ }
389
+ };
390
+ // Helper functions for type strengths/weaknesses
391
+ export const getItemTypeStrength = (type) => {
392
+ switch (type) {
393
+ case "Magic":
394
+ case "Cloth":
395
+ return "Brute";
396
+ case "Bludgeon":
397
+ case "Metal":
398
+ return "Hunter";
399
+ case "Blade":
400
+ case "Hide":
401
+ return "Magic";
402
+ default:
403
+ return "";
404
+ }
405
+ };
406
+ export const getItemTypeWeakness = (type) => {
407
+ switch (type) {
408
+ case "Magic":
409
+ case "Cloth":
410
+ return "Hunter";
411
+ case "Bludgeon":
412
+ case "Metal":
413
+ return "Magic";
414
+ case "Blade":
415
+ case "Hide":
416
+ return "Brute";
417
+ default:
418
+ return "";
419
+ }
420
+ };
421
+ export const getWeaponTypeStrength = (type) => {
422
+ switch (type) {
423
+ case "Bludgeon":
424
+ return "Hide";
425
+ case "Magic":
426
+ return "Metal";
427
+ case "Blade":
428
+ return "Cloth";
429
+ default:
430
+ return "";
431
+ }
432
+ };
433
+ export const getWeaponTypeWeakness = (type) => {
434
+ switch (type) {
435
+ case "Bludgeon":
436
+ return "Cloth";
437
+ case "Magic":
438
+ return "Hide";
439
+ case "Blade":
440
+ return "Metal";
441
+ default:
442
+ return "";
443
+ }
444
+ };
445
+ export const getArmorTypeStrength = (type) => {
446
+ switch (type) {
447
+ case "Cloth":
448
+ return "Bludgeon";
449
+ case "Hide":
450
+ return "Magic";
451
+ case "Metal":
452
+ return "Blade";
453
+ default:
454
+ return "";
455
+ }
456
+ };
457
+ export const getArmorTypeWeakness = (type) => {
458
+ switch (type) {
459
+ case "Cloth":
460
+ return "Blade";
461
+ case "Hide":
462
+ return "Bludgeon";
463
+ case "Metal":
464
+ return "Magic";
465
+ default:
466
+ return "";
467
+ }
468
+ };
469
+ export const beastPowerPercent = (adventurerLevel, power) => {
470
+ const max_beast_level = adventurerLevel * 3;
471
+ let base_level = 1;
472
+ if (adventurerLevel >= 50) {
473
+ base_level += 80;
474
+ }
475
+ else if (adventurerLevel >= 40) {
476
+ base_level += 40;
477
+ }
478
+ else if (adventurerLevel >= 30) {
479
+ base_level += 20;
480
+ }
481
+ else if (adventurerLevel >= 20) {
482
+ base_level += 10;
483
+ }
484
+ const adjusted_max_power = (base_level + max_beast_level) * 5 - base_level;
485
+ const adjusted_power = Math.max(power - base_level, 1);
486
+ return (adjusted_power / adjusted_max_power) * 100;
487
+ };
488
+ export const getCollectableTraits = (seed) => {
489
+ if (seed === BigInt(0)) {
490
+ return {
491
+ shiny: false,
492
+ animated: false,
493
+ };
494
+ }
495
+ const shiny_seed = Number(seed & BigInt(0xffffffff)) % 10000;
496
+ const shiny = shiny_seed < 500;
497
+ // Use the upper 32 bits for animated trait
498
+ const animated_seed = Number((seed / BigInt(0x100000000)) & BigInt(0xffffffff)) % 10000;
499
+ const animated = animated_seed < 500;
500
+ return {
501
+ shiny,
502
+ animated,
503
+ };
504
+ };
505
+ export const collectableImage = (name, traits) => {
506
+ if (name === "Ducky") {
507
+ return getBeastImage(name);
508
+ }
509
+ // Karats dungeon: the Carbuncle's collectable portrait is the karat it
510
+ // guards. Static fallback (first reward's art) for surfaces without live
511
+ // dungeon state — the combat overlays swap in the NEXT claimable karat via
512
+ // useNextKarat.
513
+ if (name === CARBUNCLE_NAME) {
514
+ return nextKaratImage(null);
515
+ }
516
+ // The Black Shuck ships as a standalone collection rather than as an entry in
517
+ // the beasts NFT art set, so there is no /images/nfts variant to select on
518
+ // shiny/animated — the one portrait covers every trait combination.
519
+ if (name === BLACK_SHUCK_NAME) {
520
+ return getBeastImage(BLACK_SHUCK_NAME);
521
+ }
522
+ if (traits.shiny && traits.animated) {
523
+ return `/images/nfts/animated/shiny/${name.toLowerCase()}.gif`;
524
+ }
525
+ else if (traits.animated) {
526
+ return `/images/nfts/animated/regular/${name.toLowerCase()}.gif`;
527
+ }
528
+ else if (traits.shiny) {
529
+ return `/images/nfts/shiny/${name.toLowerCase()}.png`;
530
+ }
531
+ else {
532
+ return `/images/nfts/regular/${name.toLowerCase()}.png`;
533
+ }
534
+ };
535
+ //# sourceMappingURL=beast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beast.js","sourceRoot":"","sources":["../../src/rules/beast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { Adventurer, Beast, CombatStats, Equipment, Item } from "../types.js";
2
+ export declare const getLocationName: (location: string | object | undefined) => string;
3
+ export declare const calculateLevel: (xp: number) => number;
4
+ /**
5
+ * Calculate greed reward matching the on-chain formula:
6
+ * reward = pool_balance * weight(level) / SCALE
7
+ *
8
+ * @param poolBalance - Total pool balance in wei (as bigint or string)
9
+ * @param level - Adventurer level (1-40)
10
+ * @returns Reward amount as a human-readable number (divided by 1e18)
11
+ */
12
+ export declare const calculateGreedRewardFromPool: (poolBalance: bigint, level: number) => number;
13
+ export declare const calculateSurvivalRewardAmount: (dungeonId: string, level: number, poolBalance?: bigint) => number | null;
14
+ export declare const calculateSurvivalReward: (dungeonId: string, level: number, poolBalance?: bigint) => string | null;
15
+ export declare const calculateHyperGreedReward: (entryWei: bigint, level: number, pegWei: bigint) => number;
16
+ export declare const calculateNextLevelXP: (currentLevel: number, item?: boolean) => number;
17
+ export declare const calculateProgress: (xp: number, item?: boolean) => number;
18
+ export declare const getNewItemsEquipped: (newEquipment: Equipment, oldEquipment: Equipment) => Item[];
19
+ export declare const incrementBeastsCollected: (gameId: string) => void;
20
+ export declare const calculateAttackDamage: (weapon: Item, adventurer: Adventurer, beast: Beast | null) => {
21
+ baseDamage: number;
22
+ criticalDamage: number;
23
+ };
24
+ export declare const ability_based_percentage: (adventurer_xp: number, relevant_stat: number) => number;
25
+ export declare const ability_based_avoid_threat: (adventurer_level: number, relevant_stat: number, rnd: number) => boolean;
26
+ export declare const ability_based_damage_reduction: (adventurer_xp: number, relevant_stat: number) => number;
27
+ export declare const calculateBeastDamage: (beast: Beast, adventurer: Adventurer, armor: Item) => {
28
+ baseDamage: number;
29
+ criticalDamage: number;
30
+ };
31
+ export declare function elementalAdjustedDamage(base_attack: number, weapon_type: string, armor_type: string): number;
32
+ export declare function strength_dmg(damage: number, strength: number): number;
33
+ export declare const calculateCombatStats: (adventurer: Adventurer, bagItems: Item[], beast: Beast | null) => CombatStats;
34
+ export declare const calculateGoldReward: (beast: Beast, ring: Item | null) => number;
35
+ //# sourceMappingURL=game.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game.d.ts","sourceRoot":"","sources":["../../src/rules/game.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAK9E,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,GAAG,MAAM,GAAG,SAAS,WAKpE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,WAGxC,CAAC;AAiDF;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,GAAI,aAAa,MAAM,EAAE,OAAO,MAAM,KAAG,MAKjF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,WAAW,MAAM,EACjB,OAAO,MAAM,EACb,cAAc,MAAM,KACnB,MAAM,GAAG,IAaX,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,WAAW,MAAM,EACjB,OAAO,MAAM,EACb,cAAc,MAAM,KACnB,MAAM,GAAG,IAKX,CAAC;AAmDF,eAAO,MAAM,yBAAyB,GACpC,UAAU,MAAM,EAChB,OAAO,MAAM,EACb,QAAQ,MAAM,KACb,MASF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,EAAE,OAAM,OAAe,WAM/E,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,IAAI,MAAM,EAAE,OAAM,OAAe,WAKlE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,cAAc,SAAS,EAAE,cAAc,SAAS,WAgBnF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM,SAGtD,CAAC;AAiDF,eAAO,MAAM,qBAAqB,GAChC,QAAQ,IAAI,EACZ,YAAY,UAAU,EACtB,OAAO,KAAK,GAAG,IAAI;;;CA6DpB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,eAAe,MAAM,EAAE,eAAe,MAAM,WAQpF,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,kBAAkB,MAAM,EACxB,eAAe,MAAM,EACrB,KAAK,MAAM,YAQZ,CAAC;AAEF,eAAO,MAAM,8BAA8B,GAAI,eAAe,MAAM,EAAE,eAAe,MAAM,WAc1F,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,KAAK,EAAE,YAAY,UAAU,EAAE,OAAO,IAAI;;;CAqDrF,CAAC;AAyBF,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CAoBR;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrE;AAGD,eAAO,MAAM,oBAAoB,GAC/B,YAAY,UAAU,EACtB,UAAU,IAAI,EAAE,EAChB,OAAO,KAAK,GAAG,IAAI,KAClB,WA4GF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,OAAO,KAAK,EAAE,MAAM,IAAI,GAAG,IAAI,WAUlE,CAAC"}