You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

625 lines
13 KiB

  1. let statsFishingRod = require('./statsFishingRod');
  2. module.exports = {
  3. generators: {
  4. elementDmgPercent: function (item, level, blueprint, perfection, calcPerfection) {
  5. let max = (level / 6.7);
  6. if (calcPerfection)
  7. return (calcPerfection / max);
  8. else if (perfection === null)
  9. return random.norm(1, max) * (blueprint.statMult.elementDmgPercent || 1);
  10. return max * perfection * (blueprint.statMult.elementDmgPercent || 1);
  11. },
  12. addCritMultiplier: function (item, level, blueprint, perfection, calcPerfection) {
  13. let div = 1 / 11;
  14. if (item.slot === 'twoHanded')
  15. div *= 2;
  16. let max = (level * 15) * div;
  17. if (calcPerfection)
  18. return (calcPerfection / max);
  19. else if (perfection === null)
  20. return random.norm(1, max) * (blueprint.statMult.addCritMultiplier || 1);
  21. return max * perfection * (blueprint.statMult.addCritMultiplier || 1);
  22. },
  23. addCritChance: function (item, level, blueprint, perfection, calcPerfection) {
  24. let div = 1 / 11;
  25. if (item.slot === 'twoHanded')
  26. div *= 2;
  27. let max = (level - 3) * 50 * div;
  28. if (calcPerfection)
  29. return (calcPerfection / max);
  30. else if (perfection === null)
  31. return random.norm(1, max) * (blueprint.statMult.addCritChance || 1);
  32. return max * perfection * (blueprint.statMult.addCritChance || 1);
  33. },
  34. vit: function (item, level, blueprint, perfection, calcPerfection) {
  35. let div = 1 / 11;
  36. if (item.slot === 'twoHanded')
  37. div *= 2;
  38. let max = ((-0.6340155 + (13.68923 * level) - (0.34383 * Math.pow(level, 2)) + (0.06754871 * Math.pow(level, 3)) + (0.000174046 * Math.pow(level, 4)) + (0.000007675887 * Math.pow(level, 5))) / 10) * div;
  39. if (calcPerfection)
  40. return (calcPerfection / max);
  41. else if (perfection === null)
  42. return random.norm(1, max) * (blueprint.statMult.vit || 1);
  43. return max * perfection * (blueprint.statMult.vit || 1);
  44. },
  45. mainStat: function (item, level, blueprint, perfection, calcPerfection) {
  46. let div = 1 / 11;
  47. if (item.slot === 'twoHanded')
  48. div *= 2;
  49. let min = (level / 15) * div;
  50. let max = (level * 5) * div;
  51. if (calcPerfection)
  52. return ((calcPerfection - min) / (max - min));
  53. else if (perfection === null)
  54. return random.norm(min, max) * (blueprint.statMult.mainStat || 1);
  55. return (min + ((max - min) * perfection)) * (blueprint.statMult.mainStat || 1);
  56. },
  57. armor: function (item, level, blueprint, perfection, calcPerfection) {
  58. let min = (level * 20);
  59. let max = (level * 50);
  60. if (calcPerfection)
  61. return ((calcPerfection - min) / (max - min));
  62. else if (perfection === null)
  63. return random.norm(min, max) * blueprint.statMult.armor;
  64. return (min + ((max - min) * perfection)) * (blueprint.statMult.armor || 1);
  65. },
  66. elementResist: function (item, level, blueprint, perfection, calcPerfection) {
  67. let div = 1 / 11;
  68. if (item.slot === 'twoHanded')
  69. div *= 2;
  70. if (calcPerfection)
  71. return (calcPerfection / (100 * div));
  72. else if (perfection === null)
  73. return random.norm(1, 100) * (blueprint.statMult.elementResist || 1) * div;
  74. return ~~((1 + (99 * perfection)) * (blueprint.statMult.elementResist || 1) * div);
  75. },
  76. regenHp: function (item, level, blueprint, perfection, calcPerfection) {
  77. let div = 1 / 11;
  78. if (item.slot === 'twoHanded')
  79. div *= 2;
  80. let max = (-0.05426729 + (3.477385 * level) - (0.03890282 * Math.pow(level, 2)) + (0.009244822 * Math.pow(level, 3)) + (0.0001700915 * Math.pow(level, 4)) - (0.00000138085 * Math.pow(level, 5))) * div;
  81. if (calcPerfection)
  82. return (calcPerfection / max);
  83. else if (perfection === null)
  84. return random.norm(1, max) * (blueprint.statMult.regenHp || 1);
  85. return max * perfection * (blueprint.statMult.regenHp || 1);
  86. },
  87. lvlRequire: function (item, level, blueprint, perfection, calcPerfection) {
  88. let max = ~~(level / 2);
  89. if (calcPerfection)
  90. return (calcPerfection / max);
  91. else if (perfection === null)
  92. return random.norm(1, max) * (blueprint.statMult.lvlRequire || 1);
  93. return max * perfection * (blueprint.statMult.lvlRequire || 1);
  94. }
  95. },
  96. stats: {
  97. vit: {
  98. generator: 'vit'
  99. },
  100. regenHp: {
  101. generator: 'regenHp'
  102. },
  103. manaMax: {
  104. min: 1,
  105. max: 8
  106. },
  107. regenMana: {
  108. min: 1,
  109. max: 5
  110. },
  111. lvlRequire: {
  112. level: {
  113. min: 5
  114. },
  115. generator: 'lvlRequire'
  116. },
  117. str: {
  118. generator: 'mainStat'
  119. },
  120. int: {
  121. generator: 'mainStat'
  122. },
  123. dex: {
  124. generator: 'mainStat'
  125. },
  126. elementAllResist: {
  127. level: {
  128. min: 25
  129. },
  130. generator: 'elementResist'
  131. },
  132. elementArcaneResist: {
  133. level: {
  134. min: 15
  135. },
  136. generator: 'elementResist'
  137. },
  138. elementFrostResist: {
  139. level: {
  140. min: 15
  141. },
  142. generator: 'elementResist'
  143. },
  144. elementFireResist: {
  145. level: {
  146. min: 15
  147. },
  148. generator: 'elementResist'
  149. },
  150. elementHolyResist: {
  151. level: {
  152. min: 15
  153. },
  154. generator: 'elementResist'
  155. },
  156. elementPoisonResist: {
  157. level: {
  158. min: 15
  159. },
  160. generator: 'elementResist'
  161. },
  162. elementAllResist: {
  163. level: {
  164. min: 15
  165. },
  166. generator: 'elementResist'
  167. },
  168. elementArcanePercent: {
  169. level: {
  170. min: 10
  171. },
  172. ignore: true,
  173. generator: 'elementDmgPercent'
  174. },
  175. elementFrostPercent: {
  176. level: {
  177. min: 10
  178. },
  179. ignore: true,
  180. generator: 'elementDmgPercent'
  181. },
  182. elementFirePercent: {
  183. level: {
  184. min: 10
  185. },
  186. ignore: true,
  187. generator: 'elementDmgPercent'
  188. },
  189. elementHolyPercent: {
  190. level: {
  191. min: 10
  192. },
  193. ignore: true,
  194. generator: 'elementDmgPercent'
  195. },
  196. elementPoisonPercent: {
  197. level: {
  198. min: 10
  199. },
  200. ignore: true,
  201. generator: 'elementDmgPercent'
  202. },
  203. physicalPercent: {
  204. level: {
  205. min: 10
  206. },
  207. ignore: true,
  208. generator: 'elementDmgPercent'
  209. },
  210. elementPercent: {
  211. level: {
  212. min: 10
  213. },
  214. ignore: true,
  215. generator: 'elementDmgPercent'
  216. },
  217. spellPercent: {
  218. level: {
  219. min: 10
  220. },
  221. ignore: true,
  222. generator: 'elementDmgPercent'
  223. },
  224. allAttributes: {
  225. generator: 'mainStat',
  226. ignore: true
  227. },
  228. attackSpeed: {
  229. min: 1,
  230. max: 8.75,
  231. ignore: true
  232. },
  233. castSpeed: {
  234. min: 1,
  235. max: 8.75,
  236. ignore: true
  237. },
  238. armor: {
  239. generator: 'armor',
  240. ignore: true
  241. },
  242. blockAttackChance: {
  243. min: 1,
  244. max: 10,
  245. ignore: true
  246. },
  247. blockSpellChance: {
  248. min: 1,
  249. max: 10,
  250. ignore: true
  251. },
  252. dodgeAttackChance: {
  253. min: 1,
  254. max: 10,
  255. ignore: true
  256. },
  257. dodgeSpellChance: {
  258. min: 1,
  259. max: 10,
  260. ignore: true
  261. },
  262. addCritChance: {
  263. generator: 'addCritChance',
  264. level: {
  265. min: 7
  266. }
  267. },
  268. addCritMultiplier: {
  269. generator: 'addCritMultiplier',
  270. level: {
  271. min: 12
  272. }
  273. },
  274. addAttackCritChance: {
  275. generator: 'addCritChance',
  276. level: {
  277. min: 7
  278. }
  279. },
  280. addAttackCritMultiplier: {
  281. generator: 'addCritMultiplier',
  282. level: {
  283. min: 12
  284. }
  285. },
  286. addSpellCritChance: {
  287. generator: 'addCritChance',
  288. level: {
  289. min: 7
  290. }
  291. },
  292. addSpellCritMultiplier: {
  293. generator: 'addCritMultiplier',
  294. level: {
  295. min: 12
  296. }
  297. },
  298. magicFind: {
  299. min: 1,
  300. max: 15
  301. },
  302. itemQuantity: {
  303. min: 2,
  304. max: 27
  305. },
  306. xpIncrease: {
  307. min: 1,
  308. max: 6
  309. },
  310. sprintChance: {
  311. min: 1,
  312. max: 20,
  313. ignore: true
  314. }
  315. },
  316. slots: {
  317. feet: {
  318. sprintChance: {
  319. min: 1,
  320. max: 20
  321. },
  322. dodgeAttackChance: {
  323. min: 1,
  324. max: 10
  325. },
  326. dodgeSpellChance: {
  327. min: 1,
  328. max: 10
  329. }
  330. },
  331. offHand: {
  332. },
  333. trinket: {
  334. attackSpeed: {
  335. min: 1,
  336. max: 8.75
  337. },
  338. castSpeed: {
  339. min: 1,
  340. max: 8.75
  341. }
  342. },
  343. finger: {
  344. elementArcanePercent: {
  345. generator: 'elementDmgPercent'
  346. },
  347. elementFrostPercent: {
  348. generator: 'elementDmgPercent'
  349. },
  350. elementFirePercent: {
  351. generator: 'elementDmgPercent'
  352. },
  353. elementHolyPercent: {
  354. generator: 'elementDmgPercent'
  355. },
  356. elementPoisonPercent: {
  357. generator: 'elementDmgPercent'
  358. },
  359. elementPercent: {
  360. generator: 'elementDmgPercent'
  361. },
  362. physicalPercent: {
  363. generator: 'elementDmgPercent'
  364. },
  365. spellPercent: {
  366. generator: 'elementDmgPercent'
  367. },
  368. allAttributes: {
  369. generator: 'mainStat'
  370. },
  371. attackSpeed: {
  372. min: 1,
  373. max: 8.75
  374. },
  375. castSpeed: {
  376. min: 1,
  377. max: 8.75
  378. }
  379. },
  380. neck: {
  381. elementArcanePercent: {
  382. generator: 'elementDmgPercent'
  383. },
  384. elementFrostPercent: {
  385. generator: 'elementDmgPercent'
  386. },
  387. elementFirePercent: {
  388. generator: 'elementDmgPercent'
  389. },
  390. elementHolyPercent: {
  391. generator: 'elementDmgPercent'
  392. },
  393. elementPoisonPercent: {
  394. generator: 'elementDmgPercent'
  395. },
  396. physicalPercent: {
  397. generator: 'elementDmgPercent'
  398. },
  399. elementPercent: {
  400. generator: 'elementDmgPercent'
  401. },
  402. spellPercent: {
  403. generator: 'elementDmgPercent'
  404. },
  405. allAttributes: {
  406. generator: 'mainStat'
  407. },
  408. attackSpeed: {
  409. min: 1,
  410. max: 8.75
  411. },
  412. castSpeed: {
  413. min: 1,
  414. max: 8.75
  415. }
  416. }
  417. },
  418. generate: function (item, blueprint, result) {
  419. if (item.slot === 'tool') {
  420. statsFishingRod.generate(item, blueprint, result);
  421. return;
  422. }
  423. if (!blueprint.statCount)
  424. item.stats = {};
  425. if (blueprint.noStats)
  426. return;
  427. //If we enchant something we don't add armor
  428. if (!blueprint.statMult)
  429. blueprint.statMult = {};
  430. for (let s in blueprint.statMult) {
  431. if (blueprint.statMult[s] > 0)
  432. this.buildStat(item, blueprint, s);
  433. }
  434. let statCount = blueprint.statCount || (item.quality + 1);
  435. if (blueprint.forceStats) {
  436. for (let i = 0; i < Math.min(statCount, blueprint.forceStats.length); i++) {
  437. let choice = blueprint.forceStats[i];
  438. this.buildStat(item, blueprint, choice, result);
  439. statCount--;
  440. }
  441. }
  442. let implicitStat = blueprint.implicitStat;
  443. if (implicitStat) {
  444. let value = implicitStat.value[0] + ~~(Math.random() * (implicitStat.value[1] - implicitStat.value[0]));
  445. item.implicitStats = [{
  446. stat: implicitStat.stat,
  447. value: value
  448. }];
  449. }
  450. if (blueprint.stats) {
  451. let useStats = extend(true, [], blueprint.stats);
  452. let addStats = Math.min(statCount, blueprint.stats.length);
  453. for (let i = 0; i < addStats; i++) {
  454. let choice = useStats[~~(Math.random() * useStats.length)];
  455. useStats.spliceFirstWhere(s => s === choice);
  456. this.buildStat(item, blueprint, choice, result);
  457. statCount--;
  458. }
  459. }
  460. for (let i = 0; i < statCount; i++)
  461. this.buildStat(item, blueprint, null, result);
  462. for (let s in item.stats) {
  463. item.stats[s] = Math.ceil(item.stats[s]);
  464. if (item.stats[s] === 0)
  465. delete item.stats[s];
  466. }
  467. },
  468. buildStat: function (item, blueprint, stat, result, isImplicit) {
  469. let slotStats = this.slots[item.slot] || {};
  470. let statOptions = extend(true, {}, this.stats, slotStats || {});
  471. for (let p in statOptions) {
  472. if ((!slotStats[p]) || (slotStats[p].ignore))
  473. continue;
  474. delete statOptions[p].ignore;
  475. }
  476. let statBlueprint = null;
  477. let value = null;
  478. if ((stat) && (stat.indexOf('|') > -1)) {
  479. let split = stat.split('|');
  480. stat = split[0];
  481. value = split[1];
  482. }
  483. if ((!stat) || (!statOptions[stat])) {
  484. let options = Object.keys(statOptions).filter(function (s) {
  485. let o = statOptions[s];
  486. if (o.ignore)
  487. return false;
  488. else if ((o.level) && (o.level.min) && (item.level < o.level.min))
  489. return false;
  490. return true;
  491. });
  492. stat = options[~~(Math.random() * options.length)];
  493. statBlueprint = statOptions[stat];
  494. } else
  495. statBlueprint = statOptions[stat];
  496. if (!value) {
  497. if (statBlueprint.generator) {
  498. let level = item.originalLevel || item.level;
  499. value = Math.ceil(this.generators[statBlueprint.generator](item, level, blueprint, blueprint.perfection));
  500. } else if (!blueprint.perfection)
  501. value = Math.ceil(random.norm(statBlueprint.min, statBlueprint.max));
  502. else
  503. value = statBlueprint.min + ((statBlueprint.max - statBlueprint.min) * blueprint.perfection);
  504. }
  505. if ((result) && (result.addStatMsgs)) {
  506. result.addStatMsgs.push({
  507. stat: stat,
  508. value: value
  509. });
  510. if (!item.enchantedStats)
  511. item.enchantedStats = {};
  512. if (item.enchantedStats[stat])
  513. item.enchantedStats[stat] += value;
  514. else
  515. item.enchantedStats[stat] = value;
  516. }
  517. if (stat === 'lvlRequire') {
  518. if (!item.originalLevel)
  519. item.originalLevel = item.level;
  520. item.level -= value;
  521. if (item.level < 1)
  522. item.level = 1;
  523. }
  524. if (item.stats[stat])
  525. value += item.stats[stat];
  526. item.stats[stat] = value;
  527. },
  528. rescale: function (item, level) {
  529. let stats = item.stats;
  530. let nStats = extend(true, {}, stats);
  531. let bpt = {
  532. statMult: {}
  533. };
  534. for (let p in stats) {
  535. let generator = this.stats[p].generator;
  536. if (!generator)
  537. continue;
  538. else if (['lvlRequire'].indexOf(p) > -1)
  539. continue;
  540. generator = this.generators[generator];
  541. let perfection = generator(item, item.originalLevel || item.level, bpt, null, stats[p]);
  542. nStats[p] = Math.ceil(generator(item, level, bpt, perfection));
  543. }
  544. return nStats;
  545. }
  546. };