@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,462 @@
1
+ import { BEAST_MIN_DAMAGE } from "../constants/beast.js";
2
+ import { MIN_DAMAGE } from "../constants/game.js";
3
+ import { getArmorType, getAttackType } from "./beast.js";
4
+ import { ItemType, ItemUtils } from "./loot.js";
5
+ export const getLocationName = (location) => {
6
+ if (typeof location === "object") {
7
+ return Object.keys(location)[0];
8
+ }
9
+ return location || "None";
10
+ };
11
+ export const calculateLevel = (xp) => {
12
+ if (xp === 0)
13
+ return 1;
14
+ return Math.floor(Math.sqrt(xp));
15
+ };
16
+ // 1.2x exponential curve weights matching greed.cairo get_reward_weight()
17
+ // weight[L] = 0.25 * (5/6)^(40-L) * 1e18
18
+ const GREED_REWARD_WEIGHTS = {
19
+ 1: 204113351038987n,
20
+ 2: 244936021246785n,
21
+ 3: 293923225496142n,
22
+ 4: 352707870595371n,
23
+ 5: 423249444714446n,
24
+ 6: 507899333657336n,
25
+ 7: 609479200388804n,
26
+ 8: 731375040466565n,
27
+ 9: 877650048559878n,
28
+ 10: 1053180058271854n,
29
+ 11: 1263816069926225n,
30
+ 12: 1516579283911470n,
31
+ 13: 1819895140693765n,
32
+ 14: 2183874168832519n,
33
+ 15: 2620649002599023n,
34
+ 16: 3144778803118828n,
35
+ 17: 3773734563742594n,
36
+ 18: 4528481476491113n,
37
+ 19: 5434177771789336n,
38
+ 20: 6521013326147204n,
39
+ 21: 7825215991376645n,
40
+ 22: 9390259189651975n,
41
+ 23: 11268311027582371n,
42
+ 24: 13521973233098846n,
43
+ 25: 16226367879718616n,
44
+ 26: 19471641455662340n,
45
+ 27: 23365969746794808n,
46
+ 28: 28039163696153770n,
47
+ 29: 33646996435384524n,
48
+ 30: 40376395722461429n,
49
+ 31: 48451674866953715n,
50
+ 32: 58142009840344458n,
51
+ 33: 69770411808413350n,
52
+ 34: 83724494170096020n,
53
+ 35: 100469393004115225n,
54
+ 36: 120563271604938270n,
55
+ 37: 144675925925925925n,
56
+ 38: 173611111111111110n,
57
+ 39: 208333333333333333n,
58
+ 40: 250000000000000000n,
59
+ };
60
+ const SCALE = 1000000000000000000n;
61
+ /**
62
+ * Calculate greed reward matching the on-chain formula:
63
+ * reward = pool_balance * weight(level) / SCALE
64
+ *
65
+ * @param poolBalance - Total pool balance in wei (as bigint or string)
66
+ * @param level - Adventurer level (1-40)
67
+ * @returns Reward amount as a human-readable number (divided by 1e18)
68
+ */
69
+ export const calculateGreedRewardFromPool = (poolBalance, level) => {
70
+ const cappedLevel = Math.min(Math.max(level, 1), 40);
71
+ const weight = GREED_REWARD_WEIGHTS[cappedLevel];
72
+ const rewardWei = (poolBalance * weight) / SCALE;
73
+ return Number(rewardWei) / 1e18;
74
+ };
75
+ export const calculateSurvivalRewardAmount = (dungeonId, level, poolBalance) => {
76
+ if (dungeonId === "greed") {
77
+ if (poolBalance !== undefined) {
78
+ return parseFloat(calculateGreedRewardFromPool(poolBalance, level).toFixed(1));
79
+ }
80
+ // Fallback when pool balance unknown
81
+ const cappedLevel = Math.min(level, 40);
82
+ return parseFloat((2.0 * Math.pow(1.2, cappedLevel - 1)).toFixed(1));
83
+ }
84
+ if (dungeonId === "yield") {
85
+ return level + 10;
86
+ }
87
+ return null;
88
+ };
89
+ export const calculateSurvivalReward = (dungeonId, level, poolBalance) => {
90
+ const amount = calculateSurvivalRewardAmount(dungeonId, level, poolBalance);
91
+ if (amount === null)
92
+ return "No Reward";
93
+ if (dungeonId === "yield")
94
+ return `${amount}`;
95
+ return `${amount} $SURVIVOR`;
96
+ };
97
+ // Per-level reward multiplier matching hyper_greed.cairo level_multiplier() — a
98
+ // 1.2x exponential curve from ~0.2x (level 1) to exactly 250x (level 40), 1e18-scaled.
99
+ const HYPER_GREED_MULTIPLIERS = {
100
+ 1: 204113351038987000n,
101
+ 2: 244936021246785000n,
102
+ 3: 293923225496142000n,
103
+ 4: 352707870595371000n,
104
+ 5: 423249444714446000n,
105
+ 6: 507899333657336000n,
106
+ 7: 609479200388804000n,
107
+ 8: 731375040466565000n,
108
+ 9: 877650048559878000n,
109
+ 10: 1053180058271854000n,
110
+ 11: 1263816069926225000n,
111
+ 12: 1516579283911470000n,
112
+ 13: 1819895140693765000n,
113
+ 14: 2183874168832519000n,
114
+ 15: 2620649002599023000n,
115
+ 16: 3144778803118828000n,
116
+ 17: 3773734563742594000n,
117
+ 18: 4528481476491113000n,
118
+ 19: 5434177771789336000n,
119
+ 20: 6521013326147204000n,
120
+ 21: 7825215991376645000n,
121
+ 22: 9390259189651975000n,
122
+ 23: 11268311027582371000n,
123
+ 24: 13521973233098846000n,
124
+ 25: 16226367879718616000n,
125
+ 26: 19471641455662340000n,
126
+ 27: 23365969746794808000n,
127
+ 28: 28039163696153770000n,
128
+ 29: 33646996435384524000n,
129
+ 30: 40376395722461429000n,
130
+ 31: 48451674866953715000n,
131
+ 32: 58142009840344458000n,
132
+ 33: 69770411808413350000n,
133
+ 34: 83724494170096020000n,
134
+ 35: 100469393004115225000n,
135
+ 36: 120563271604938270000n,
136
+ 37: 144675925925925925000n,
137
+ 38: 173611111111111110000n,
138
+ 39: 208333333333333333000n,
139
+ 40: 250000000000000000000n,
140
+ };
141
+ // Hyper Greed exit/surrender payout, in STRK (human number). Matches the on-chain
142
+ // `pegged_reward`: reward_strk = wager * level_multiplier(level) * peg, where the peg
143
+ // (prize-pool value / liquidity provided) is 1e18-scaled. Returns 0 below level 1.
144
+ // `entryWei` is the game's STRK wager (from the contract's `game_entry` view).
145
+ export const calculateHyperGreedReward = (entryWei, level, pegWei) => {
146
+ if (entryWei <= 0n || level < 1)
147
+ return 0;
148
+ const cappedLevel = Math.min(level, 40);
149
+ const multiplier = HYPER_GREED_MULTIPLIERS[cappedLevel];
150
+ // (wager * multiplier / 1e18) * peg / 1e18, all in wei, then to a human number.
151
+ const rewardWei = (((entryWei * multiplier) / SCALE) * pegWei) / SCALE;
152
+ // Reduce in bigint first: rewardWei exceeds Number.MAX_SAFE_INTEGER for non-trivial wagers,
153
+ // so keep 6 decimals of precision and only then convert.
154
+ return Number(rewardWei / 10n ** 12n) / 1e6;
155
+ };
156
+ export const calculateNextLevelXP = (currentLevel, item = false) => {
157
+ if (item) {
158
+ return Math.min(400, (currentLevel + 1) ** 2);
159
+ }
160
+ return (currentLevel + 1) ** 2;
161
+ };
162
+ export const calculateProgress = (xp, item = false) => {
163
+ const currentLevel = calculateLevel(xp);
164
+ const nextLevelXP = calculateNextLevelXP(currentLevel, item);
165
+ const currentLevelXP = currentLevel ** 2;
166
+ return ((xp - currentLevelXP) / (nextLevelXP - currentLevelXP)) * 100;
167
+ };
168
+ export const getNewItemsEquipped = (newEquipment, oldEquipment) => {
169
+ if (!newEquipment || !oldEquipment)
170
+ return [];
171
+ const newItems = [];
172
+ // Check each equipment slot in the current adventurer
173
+ Object.entries(newEquipment).forEach(([slot, currentItem]) => {
174
+ const initialItem = oldEquipment[slot];
175
+ // Only add if there's a current item and it's different from the initial item
176
+ if (currentItem.id !== 0 && currentItem.id !== initialItem.id) {
177
+ newItems.push(currentItem);
178
+ }
179
+ });
180
+ return newItems;
181
+ };
182
+ export const incrementBeastsCollected = (gameId) => {
183
+ const currentCount = parseInt(localStorage.getItem(`beast_collected_${gameId}`) || "0");
184
+ localStorage.setItem(`beast_collected_${gameId}`, (currentCount + 1).toString());
185
+ };
186
+ // Calculate critical hit bonus based on luck and ring
187
+ const critical_hit_bonus = (base_damage, ring) => {
188
+ let total = 0;
189
+ total = base_damage;
190
+ // Titanium Ring gives 3% bonus per level on critical hits
191
+ if (ring && ItemUtils.getItemName(ring.id) === "Titanium Ring" && total > 0) {
192
+ const ringLevel = calculateLevel(ring.xp);
193
+ total += Math.floor((total * 3 * ringLevel) / 100);
194
+ }
195
+ return total;
196
+ };
197
+ // Calculate weapon special bonus based on matching specials
198
+ const calculateWeaponSpecialBonus = (weaponId, weaponLevel, itemSpecialsSeed, beastPrefix, beastSuffix, baseDamage, ring) => {
199
+ if (!beastPrefix && !beastSuffix)
200
+ return 0;
201
+ const weaponSpecials = ItemUtils.getSpecials(weaponId, weaponLevel, itemSpecialsSeed);
202
+ let bonus = 0;
203
+ // Special2 (prefix) match gives 8x damage
204
+ if (weaponSpecials.prefix && weaponSpecials.prefix === beastPrefix) {
205
+ bonus += baseDamage * 8;
206
+ }
207
+ // Special3 (suffix) match gives 2x damage
208
+ if (weaponSpecials.suffix && weaponSpecials.suffix === beastSuffix) {
209
+ bonus += baseDamage * 2;
210
+ }
211
+ // Platinum Ring gives 3% bonus per level on special matches
212
+ if (ItemUtils.getItemName(ring.id) === "Platinum Ring" && bonus > 0) {
213
+ const ringLevel = calculateLevel(ring.xp);
214
+ bonus += Math.floor((bonus * 3 * ringLevel) / 100);
215
+ }
216
+ return bonus;
217
+ };
218
+ export const calculateAttackDamage = (weapon, adventurer, beast) => {
219
+ if (!weapon)
220
+ return { baseDamage: MIN_DAMAGE, criticalDamage: MIN_DAMAGE }; // Minimum damage
221
+ const weaponLevel = calculateLevel(weapon.xp);
222
+ const weaponTier = ItemUtils.getItemTier(weapon.id);
223
+ const baseAttack = weaponLevel * (6 - Number(weaponTier));
224
+ if (!beast) {
225
+ const strBonus = Math.floor(baseAttack * (adventurer.stats.strength / 10));
226
+ return {
227
+ baseDamage: baseAttack + strBonus,
228
+ criticalDamage: baseAttack * 2 + strBonus,
229
+ };
230
+ }
231
+ let baseArmor = 0;
232
+ let elementalDamage = 0;
233
+ const beastLevel = beast.level;
234
+ const weaponType = ItemUtils.getItemType(weapon.id);
235
+ const beastArmor = getArmorType(beast.id);
236
+ baseArmor = beastLevel * (6 - Number(beast.tier));
237
+ elementalDamage = elementalAdjustedDamage(baseAttack, weaponType, beastArmor);
238
+ // Calculate strength bonus
239
+ let strengthBonus = 0;
240
+ if (adventurer.stats.strength > 0) {
241
+ strengthBonus = Math.floor((elementalDamage * adventurer.stats.strength * 10) / 100);
242
+ }
243
+ // Calculate special name bonus damage with ring bonus
244
+ const ring = adventurer.equipment.ring;
245
+ const specialBonus = calculateWeaponSpecialBonus(weapon.id, weaponLevel, adventurer.item_specials_salt, beast.specialPrefix, beast.specialSuffix, elementalDamage, ring);
246
+ // Calculate base damage (without critical)
247
+ const baseDamage = Math.max(MIN_DAMAGE, elementalDamage + strengthBonus + specialBonus - baseArmor);
248
+ // Calculate critical hit bonus with ring bonus using adventurer's luck stat
249
+ const critBonus = critical_hit_bonus(elementalDamage, ring);
250
+ const criticalDamage = Math.max(MIN_DAMAGE, elementalDamage + strengthBonus + specialBonus + critBonus - baseArmor);
251
+ return {
252
+ baseDamage,
253
+ criticalDamage,
254
+ };
255
+ };
256
+ export const ability_based_percentage = (adventurer_xp, relevant_stat) => {
257
+ const adventurer_level = calculateLevel(adventurer_xp);
258
+ if (relevant_stat >= adventurer_level) {
259
+ return 100;
260
+ }
261
+ else {
262
+ return Math.floor((relevant_stat / adventurer_level) * 100);
263
+ }
264
+ };
265
+ export const ability_based_avoid_threat = (adventurer_level, relevant_stat, rnd) => {
266
+ if (relevant_stat >= adventurer_level) {
267
+ return true;
268
+ }
269
+ else {
270
+ const scaled_chance = (adventurer_level * rnd) / 255;
271
+ return relevant_stat > scaled_chance;
272
+ }
273
+ };
274
+ export const ability_based_damage_reduction = (adventurer_xp, relevant_stat) => {
275
+ const adventurer_level = calculateLevel(adventurer_xp);
276
+ const SCALE = 1_000_000;
277
+ let ratio = (SCALE * relevant_stat) / adventurer_level;
278
+ if (ratio > SCALE) {
279
+ ratio = SCALE;
280
+ }
281
+ const r2 = (ratio * ratio) / SCALE;
282
+ const r3 = (r2 * ratio) / SCALE;
283
+ const smooth = 3 * r2 - 2 * r3;
284
+ return Math.floor((100 * smooth) / SCALE);
285
+ };
286
+ export const calculateBeastDamage = (beast, adventurer, armor) => {
287
+ const baseAttack = beast.level * (6 - Number(beast.tier));
288
+ let baseDamage = baseAttack;
289
+ let critDamage = baseAttack;
290
+ if (armor?.id) {
291
+ const armorLevel = calculateLevel(armor.xp);
292
+ const armorValue = armorLevel * (6 - ItemUtils.getItemTier(armor.id));
293
+ // Apply elemental adjustment
294
+ const beastAttackType = getAttackType(beast.id);
295
+ const armorType = ItemUtils.getItemType(armor.id);
296
+ const elementalDamage = elementalAdjustedDamage(baseAttack, beastAttackType, armorType);
297
+ let damage = elementalDamage;
298
+ // Apply name match bonus
299
+ if (beast.specialPrefix && beast.specialSuffix) {
300
+ const itemSpecials = ItemUtils.getSpecials(armor.id, armorLevel, adventurer.item_specials_salt);
301
+ if (itemSpecials.suffix === beast.specialSuffix) {
302
+ damage += elementalDamage * 2; // Suffix match
303
+ }
304
+ if (itemSpecials.prefix === beast.specialPrefix) {
305
+ damage += elementalDamage * 8; // Prefix match
306
+ }
307
+ }
308
+ critDamage = Math.max(BEAST_MIN_DAMAGE, damage + elementalDamage - armorValue);
309
+ baseDamage = Math.max(BEAST_MIN_DAMAGE, damage - armorValue);
310
+ // Check for neck armor reduction
311
+ const neck = adventurer.equipment.neck;
312
+ if (neck_reduction(armor, neck)) {
313
+ const neckLevel = calculateLevel(neck.xp);
314
+ const neckReduction = Math.floor((armorLevel * (6 - ItemUtils.getItemTier(armor.id)) * neckLevel * 3) / 100);
315
+ baseDamage -= neckReduction;
316
+ critDamage -= neckReduction;
317
+ }
318
+ }
319
+ else {
320
+ baseDamage = Math.floor(baseAttack * 1.5);
321
+ critDamage = Math.floor(baseAttack * 1.5) * 2;
322
+ }
323
+ return {
324
+ baseDamage: Math.max(BEAST_MIN_DAMAGE, baseDamage),
325
+ criticalDamage: Math.max(BEAST_MIN_DAMAGE, critDamage),
326
+ };
327
+ };
328
+ // Check if neck item provides bonus armor reduction
329
+ const neck_reduction = (armor, neck) => {
330
+ if (!armor.id || !neck.id)
331
+ return false;
332
+ if (ItemUtils.getItemType(armor.id) === ItemType.Cloth &&
333
+ ItemUtils.getItemName(neck.id) === "Amulet")
334
+ return true;
335
+ if (ItemUtils.getItemType(armor.id) === ItemType.Hide &&
336
+ ItemUtils.getItemName(neck.id) === "Pendant")
337
+ return true;
338
+ if (ItemUtils.getItemType(armor.id) === ItemType.Metal &&
339
+ ItemUtils.getItemName(neck.id) === "Necklace")
340
+ return true;
341
+ return false;
342
+ };
343
+ export function elementalAdjustedDamage(base_attack, weapon_type, armor_type) {
344
+ const elemental_effect = Math.floor(base_attack / 2);
345
+ if ((weapon_type === ItemType.Magic && armor_type === "Metal") ||
346
+ (weapon_type === ItemType.Blade && armor_type === "Cloth") ||
347
+ (weapon_type === ItemType.Bludgeon && armor_type === "Hide")) {
348
+ return base_attack + elemental_effect;
349
+ }
350
+ if ((weapon_type === ItemType.Magic && armor_type === "Hide") ||
351
+ (weapon_type === ItemType.Blade && armor_type === "Metal") ||
352
+ (weapon_type === ItemType.Bludgeon && armor_type === "Cloth")) {
353
+ return base_attack - elemental_effect;
354
+ }
355
+ return base_attack;
356
+ }
357
+ export function strength_dmg(damage, strength) {
358
+ if (strength == 0)
359
+ return 0;
360
+ return (damage * strength * 10) / 100;
361
+ }
362
+ // Calculate combat stats
363
+ export const calculateCombatStats = (adventurer, bagItems, beast) => {
364
+ const { baseDamage, criticalDamage } = calculateAttackDamage(adventurer.equipment.weapon, adventurer, beast);
365
+ let protection = 0;
366
+ let bestProtection = 0;
367
+ const bestItems = [];
368
+ let bestWeapon = adventurer.equipment.weapon;
369
+ let bestDamage = baseDamage;
370
+ let maxBeastBaseDamage = 0;
371
+ let maxBeastCriticalDamage = 0;
372
+ if (beast) {
373
+ let totalDefense = 0;
374
+ let totalBestDefense = 0;
375
+ const maxDamage = beast.level * (6 - Number(beast.tier)) * 1.5;
376
+ bagItems
377
+ .filter((item) => ItemUtils.getItemSlot(item.id) === "Weapon")
378
+ .forEach((item) => {
379
+ const itemDamage = calculateAttackDamage(item, adventurer, beast).baseDamage;
380
+ if (itemDamage > bestDamage) {
381
+ bestDamage = itemDamage;
382
+ bestWeapon = item;
383
+ }
384
+ });
385
+ if (bestWeapon) {
386
+ bestItems.push(bestWeapon);
387
+ }
388
+ ["head", "chest", "waist", "hand", "foot"].forEach((slot) => {
389
+ const armor = adventurer.equipment[slot];
390
+ let armorDefense = 0;
391
+ if (armor.id !== 0) {
392
+ const beastDmg = calculateBeastDamage(beast, adventurer, armor);
393
+ armorDefense = Math.max(0, maxDamage - beastDmg.baseDamage);
394
+ maxBeastBaseDamage = Math.max(maxBeastBaseDamage, beastDmg.baseDamage);
395
+ maxBeastCriticalDamage = Math.max(maxBeastCriticalDamage, beastDmg.criticalDamage);
396
+ }
397
+ else {
398
+ // No armor in this slot - beast does unmitigated damage
399
+ const beastDmg = calculateBeastDamage(beast, adventurer, armor);
400
+ maxBeastBaseDamage = Math.max(maxBeastBaseDamage, beastDmg.baseDamage);
401
+ maxBeastCriticalDamage = Math.max(maxBeastCriticalDamage, beastDmg.criticalDamage);
402
+ }
403
+ let bestDefense = armorDefense;
404
+ let bestItem = null;
405
+ bagItems
406
+ .filter((item) => ItemUtils.getItemSlot(item.id).toLowerCase() === slot)
407
+ .forEach((item) => {
408
+ const itemDefense = Math.max(0, maxDamage - calculateBeastDamage(beast, adventurer, item).baseDamage);
409
+ if (itemDefense > bestDefense) {
410
+ bestDefense = itemDefense;
411
+ bestItem = item;
412
+ }
413
+ });
414
+ totalDefense += armorDefense;
415
+ totalBestDefense += bestDefense;
416
+ if (bestItem) {
417
+ bestItems.push(bestItem);
418
+ }
419
+ });
420
+ if (maxDamage <= 2) {
421
+ protection = 100;
422
+ bestProtection = 100;
423
+ }
424
+ else {
425
+ protection = Math.floor((totalDefense / ((maxDamage - BEAST_MIN_DAMAGE) * 5)) * 100);
426
+ bestProtection = Math.floor((totalBestDefense / ((maxDamage - BEAST_MIN_DAMAGE) * 5)) * 100);
427
+ }
428
+ }
429
+ let gearScore = 0;
430
+ Object.values(adventurer.equipment).forEach((item) => {
431
+ if (item.id !== 0) {
432
+ gearScore += calculateLevel(item.xp) * (6 - ItemUtils.getItemTier(item.id));
433
+ }
434
+ });
435
+ bagItems.forEach((item) => {
436
+ if (item.id !== 0) {
437
+ gearScore += calculateLevel(item.xp) * (6 - ItemUtils.getItemTier(item.id));
438
+ }
439
+ });
440
+ return {
441
+ baseDamage,
442
+ protection,
443
+ bestDamage,
444
+ bestProtection,
445
+ bestItems,
446
+ critChance: adventurer.stats.luck,
447
+ criticalDamage,
448
+ gearScore,
449
+ maxBeastBaseDamage,
450
+ maxBeastCriticalDamage,
451
+ };
452
+ };
453
+ export const calculateGoldReward = (beast, ring) => {
454
+ let goldReward = Math.floor((beast.level * (6 - Number(beast.tier))) / 2);
455
+ // Gold Ring gives 3% bonus per level on gold reward
456
+ if (ring && ItemUtils.getItemName(ring.id) === "Gold Ring" && goldReward > 0) {
457
+ const ringLevel = calculateLevel(ring.xp);
458
+ goldReward += Math.floor((goldReward * 3 * ringLevel) / 100);
459
+ }
460
+ return goldReward;
461
+ };
462
+ //# sourceMappingURL=game.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"game.js","sourceRoot":"","sources":["../../src/rules/game.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Client-only game simulation logic.
3
+ * Pure functions porting Cairo contract formulas for use in useGameCore.
4
+ */
5
+ import { Adventurer, Beast, Item, Stats } from "../types.js";
6
+ export declare const randomU8: () => number;
7
+ export declare const randomU16: () => number;
8
+ export declare const randomU32: () => number;
9
+ export declare const T5_ITEMS: (12 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 101 | 76 | 81 | 86 | 91 | 96)[];
10
+ export declare const T4_ITEMS: (75 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 100 | 80 | 85 | 90 | 95)[];
11
+ export declare const T3_ITEMS: (19 | 69 | 11 | 15 | 24 | 29 | 34 | 39 | 44 | 49 | 54 | 59 | 64 | 74 | 79 | 84 | 89 | 94 | 99)[];
12
+ export declare const T2_ITEMS: (18 | 10 | 14 | 23 | 28 | 33 | 38 | 43 | 48 | 53 | 58 | 63 | 68 | 73 | 78 | 83 | 88 | 93 | 98)[];
13
+ export declare const T1_ITEMS: (9 | 13 | 17 | 22 | 27 | 32 | 37 | 42 | 47 | 52 | 57 | 62 | 67 | 72 | 77 | 82 | 87 | 92 | 97)[];
14
+ export declare const getTierMultiplier: (tier: number) => number;
15
+ export declare const applyDamageReduction: (damage: number, reductionPercent: number) => number;
16
+ /**
17
+ * Ability-based threat avoidance (used for ambush with wisdom, dodge with intelligence).
18
+ * Returns true if the threat is avoided.
19
+ */
20
+ export declare const abilityBasedAvoidThreat: (level: number, stat: number) => boolean;
21
+ export declare const abilityBasedAvoidThreatWithRoll: (level: number, stat: number, avoidRnd?: number) => {
22
+ avoided: boolean;
23
+ rnd: number;
24
+ };
25
+ export declare const getEncounterLevel: (adventurerLevel: number, levelRnd?: number) => number;
26
+ export declare const getEncounterHealth: (adventurerLevel: number, healthRnd?: number) => number;
27
+ declare const ATTACK_SLOTS: readonly ["chest", "head", "waist", "foot", "hand"];
28
+ export type AttackSlot = (typeof ATTACK_SLOTS)[number];
29
+ export declare const getAttackLocation: (rnd?: number) => AttackSlot;
30
+ export declare const getSlotDisplayName: (slot: string) => string;
31
+ export interface GeneratedBeast {
32
+ id: number;
33
+ level: number;
34
+ health: number;
35
+ tier: number;
36
+ special2: number;
37
+ special3: number;
38
+ }
39
+ export declare const generateBeast: (adventurerLevel: number) => GeneratedBeast;
40
+ export declare const beastToBeastEvent: (beast: GeneratedBeast) => Beast;
41
+ export interface GeneratedObstacle {
42
+ id: number;
43
+ level: number;
44
+ tier: number;
45
+ type: string;
46
+ }
47
+ /** `ImplAdventurer::get_random_obstacle(level, seed, level_rnd)` when the rolls are supplied. */
48
+ export interface ObstacleRolls {
49
+ idRnd: number;
50
+ levelRnd: number;
51
+ }
52
+ export declare const generateObstacle: (adventurerLevel: number, rolls?: ObstacleRolls) => GeneratedObstacle;
53
+ export declare const calculateObstacleDamage: (obstacle: GeneratedObstacle, armor: Item, adventurerLevel: number, baseDamageReduction: number, rolls?: BeastAttackRolls) => {
54
+ damage: number;
55
+ location: string;
56
+ critical_hit: boolean;
57
+ };
58
+ export declare const getBaseXpReward: (tier: number, entityLevel: number, adventurerLevel: number) => number;
59
+ export interface DiscoveryResult {
60
+ type: "Gold" | "Health" | "Loot";
61
+ amount: number;
62
+ itemId?: number;
63
+ }
64
+ /** `ImplAdventurer::get_discovery(level, discovery_type_rnd, amount_rnd1, amount_rnd2)`. */
65
+ export interface DiscoveryRolls {
66
+ typeRnd: number;
67
+ amountRnd1: number;
68
+ amountRnd2: number;
69
+ }
70
+ export declare const getDiscovery: (adventurerLevel: number, rolls?: DiscoveryRolls) => DiscoveryResult;
71
+ export declare const increaseHealth: (adventurer: Adventurer, amount: number) => void;
72
+ export declare const decreaseHealth: (adventurer: Adventurer, amount: number) => void;
73
+ export declare const increaseGold: (adventurer: Adventurer, amount: number) => void;
74
+ export declare const increaseXp: (adventurer: Adventurer, amount: number) => void;
75
+ export declare const canExplore: (adventurer: Adventurer) => boolean;
76
+ /**
77
+ * Get the armor Item at a given attack slot.
78
+ */
79
+ export declare const getArmorAtSlot: (adventurer: Adventurer, slot: AttackSlot) => Item;
80
+ export interface LootGoldConversion {
81
+ gold: number;
82
+ reason: "owned" | "inventory_full";
83
+ }
84
+ /**
85
+ * Mirrors `_process_discovery` in the exploration contract: a discovered item
86
+ * is replaced with gold (T1=20, T2=16, T3=12, T4=8, T5=4) when the adventurer
87
+ * already owns it (equipped or in bag) or has nowhere to put it (bag full and
88
+ * equipment slot occupied). Returns null when the item would be kept.
89
+ */
90
+ export declare const getLootDiscoveryGoldConversion: (adventurer: Adventurer, bag: Item[], itemId: number) => LootGoldConversion | null;
91
+ /**
92
+ * Try to add a discovered loot item to equipment or bag.
93
+ * Returns the gold conversion if the item couldn't be added (already owned or
94
+ * inventory full), or null if the item was equipped/bagged.
95
+ */
96
+ export declare const processLootDiscovery: (adventurer: Adventurer, bag: Item[], itemId: number) => LootGoldConversion | null;
97
+ /**
98
+ * Item greatness (level) from XP, capped at 20.
99
+ */
100
+ export declare const getItemGreatness: (item: Item) => number;
101
+ /**
102
+ * Luck-based critical hit check (used for adventurer attacks).
103
+ */
104
+ /** `ImplCombat::is_critical_hit(chance, rnd)`: `chance * 256 > 100 * rnd`. */
105
+ export declare const isCriticalHit: (luck: number, criticalHitRnd?: number) => boolean;
106
+ /**
107
+ * Precompute adventurer attack damage (normal and critical) against current beast.
108
+ * Delegates to calculateAttackDamage from game.ts which includes weapon specials,
109
+ * ring name-match bonus, and ring critical hit bonus.
110
+ */
111
+ export declare const calculateAdventurerAttackDamage: (adventurer: Adventurer, beast: Beast) => {
112
+ normal: number;
113
+ crit: number;
114
+ };
115
+ /**
116
+ * Beast counter-attack against adventurer (using store Beast type).
117
+ * Delegates to calculateBeastDamage from game.ts which includes necklace armor bonus,
118
+ * elemental adjustments, and beast special name matching.
119
+ */
120
+ /**
121
+ * `rolls` mirrors `ImplBeast::beast_attack`'s two explicit random inputs. Both critical-hit
122
+ * multipliers are 1 on chain, so ambush and ordinary attacks share the `min(level, 100)` chance.
123
+ */
124
+ export interface BeastAttackRolls {
125
+ attackLocationRnd: number;
126
+ criticalHitRnd: number;
127
+ }
128
+ export declare const calculateBeastCounterAttack: (beast: Beast, adventurer: Adventurer, baseDamageReduction: number, isAmbush?: boolean, rolls?: BeastAttackRolls) => {
129
+ damage: number;
130
+ location: string;
131
+ critical_hit: boolean;
132
+ slot: AttackSlot;
133
+ };
134
+ /**
135
+ * `ImplItem::grant_xp_to_equipped_items` -- item XP plus everything a level-up drags along.
136
+ *
137
+ * The naive "just add xp, capped at 400" loop this replaces silently skipped three things that all
138
+ * live in the packed adventurer, and so all show up as settlement mismatches:
139
+ * - `item_specials_salt`, written the FIRST time any item unlocks specials and never again,
140
+ * - a bonus stat upgrade point when an item reaches max greatness,
141
+ * - the suffix/bag stat boosts (and one-time vitality health) applied at the unlock itself.
142
+ *
143
+ * `itemSpecialsRnd` is the roll the salt is seeded from -- `item_specials_seed` on a beast kill,
144
+ * the explore `rnd3` on an obstacle. Pass `undefined` to keep the old xp-only behaviour.
145
+ */
146
+ export declare const grantXpToEquippedItems: (adventurer: Adventurer, xpAmount: number, adventurerId: string | bigint, itemSpecialsRnd?: number) => void;
147
+ /**
148
+ * Equip a single item from bag into the correct equipment slot.
149
+ * If the slot is occupied, the displaced item moves to the bag.
150
+ */
151
+ export declare const equipItem: (adventurer: Adventurer, bag: Item[], itemId: number) => void;
152
+ /**
153
+ * Drop a single item from equipment or bag.
154
+ */
155
+ export declare const dropItem: (adventurer: Adventurer, bag: Item[], itemId: number) => void;
156
+ export declare const generateStartingStats: (levelSeed?: bigint) => Stats;
157
+ export {};
158
+ //# sourceMappingURL=gameSimulation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gameSimulation.d.ts","sourceRoot":"","sources":["../../src/rules/gameSimulation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAiC7D,eAAO,MAAM,QAAQ,cAAwC,CAAC;AAC9D,eAAO,MAAM,SAAS,cAA0C,CAAC;AACjE,eAAO,MAAM,SAAS,cAAgD,CAAC;AAIvE,eAAO,MAAM,QAAQ,mGAoBpB,CAAC;AAEF,eAAO,MAAM,QAAQ,yFAkBpB,CAAC;AAEF,eAAO,MAAM,QAAQ,kGAoBpB,CAAC;AAEF,eAAO,MAAM,QAAQ,kGAoBpB,CAAC;AAEF,eAAO,MAAM,QAAQ,iGAoBpB,CAAC;AAIF,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,MAEhD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,EAAE,kBAAkB,MAAM,KAAG,MAI/E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAI,OAAO,MAAM,EAAE,MAAM,MAAM,KAAG,OAKrE,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,WAAW,MAAM,KAChB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAKjC,CAAC;AAoBF,eAAO,MAAM,iBAAiB,GAAI,iBAAiB,MAAM,EAAE,WAAW,MAAM,KAAG,MAG9E,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,iBAAiB,MAAM,EAAE,YAAY,MAAM,KAAG,MAGhF,CAAC;AAIF,QAAA,MAAM,YAAY,qDAAsD,CAAC;AACzE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAOvD,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,UAEhD,CAAC;AAUF,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,MAEjD,CAAC;AA+BF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,aAAa,GAAI,iBAAiB,MAAM,KAAG,cAUvD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAO,cAAc,KAAG,KAYxD,CAAC;AAMH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iGAAiG;AACjG,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,MAAM,EACvB,QAAQ,aAAa,KACpB,iBAMF,CAAC;AAIF,eAAO,MAAM,uBAAuB,GAClC,UAAU,iBAAiB,EAC3B,OAAO,IAAI,EACX,iBAAiB,MAAM,EACvB,qBAAqB,MAAM,EAC3B,QAAQ,gBAAgB,KACvB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAyB3D,CAAC;AAIF,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,aAAa,MAAM,EACnB,iBAAiB,MAAM,KACtB,MAMF,CAAC;AAIF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,4FAA4F;AAC5F,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,GACvB,iBAAiB,MAAM,EACvB,QAAQ,cAAc,KACrB,eAwBF,CAAC;AAIF,eAAO,MAAM,cAAc,GAAI,YAAY,UAAU,EAAE,QAAQ,MAAM,KAAG,IAEvE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,YAAY,UAAU,EAAE,QAAQ,MAAM,KAAG,IAEvE,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,YAAY,UAAU,EAAE,QAAQ,MAAM,KAAG,IAErE,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,YAAY,UAAU,EAAE,QAAQ,MAAM,KAAG,IAOnE,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,YAAY,UAAU,KAAG,OAMnD,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,YAAY,UAAU,EAAE,MAAM,UAAU,KAAG,IAEzE,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAAC;CACpC;AAED;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GACzC,YAAY,UAAU,EACtB,KAAK,IAAI,EAAE,EACX,QAAQ,MAAM,KACb,kBAAkB,GAAG,IA0CvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,YAAY,UAAU,EACtB,KAAK,IAAI,EAAE,EACX,QAAQ,MAAM,KACb,kBAAkB,GAAG,IAqBvB,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,IAAI,KAAG,MAG7C,CAAC;AAEF;;GAEG;AACH,8EAA8E;AAC9E,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,iBAAiB,MAAM,KAAG,OAGrE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,GAC1C,YAAY,UAAU,EACtB,OAAO,KAAK,KACX;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAOhC,CAAC;AAEF;;;;GAIG;AACH;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,2BAA2B,GACtC,OAAO,KAAK,EACZ,YAAY,UAAU,EACtB,qBAAqB,MAAM,EAC3B,WAAU,OAAe,EACzB,QAAQ,gBAAgB,KACvB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAmB7E,CAAC;AAgJF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GACjC,YAAY,UAAU,EACtB,UAAU,MAAM,EAChB,cAAc,MAAM,GAAG,MAAM,EAC7B,kBAAkB,MAAM,KACvB,IAoCF,CAAC;AAiCF;;;GAGG;AACH,eAAO,MAAM,SAAS,GAAI,YAAY,UAAU,EAAE,KAAK,IAAI,EAAE,EAAE,QAAQ,MAAM,KAAG,IAoC/E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,YAAY,UAAU,EAAE,KAAK,IAAI,EAAE,EAAE,QAAQ,MAAM,KAAG,IA8C9E,CAAC;AAIF,eAAO,MAAM,qBAAqB,GAAI,YAAY,MAAM,KAAG,KA+B1D,CAAC"}