Guest User

Untitled

a guest
Jan 22nd, 2021
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 50.24 KB | None | 0 0
  1. STATS_SYSTEM_CONFIG = {
  2. -- BASIC CONFIG STARTS HERE
  3. -- enable/disable features so script will execute only what you want
  4. monsterLoot = false,
  5. addSlotAction = true,
  6. addLevelAction = true,
  7. PVEStat = true,
  8. xpStat = true,
  9. lootStat = true,
  10. combatStats = true,
  11. conditionStats = true,
  12.  
  13. -- don't forget to register them in actions or they will not work
  14. GEM_BASIC_LEVEL = 8310,
  15. GEM_ADD_SLOT = 8300,
  16. GEM_RANDOM = 8305,
  17. GEM_RARE = 8301,
  18. GEM_EPIC = 8302,
  19. GEM_LEGENDARY = 8303,
  20. gems_power = {
  21. [8301] = {min_wl = 0, max_wl = 4, min_el = 0.3, max_el = 0.6, sl = function() return 2 end}, -- rare
  22. [8302] = {min_wl = 3, max_wl = 6, min_el = 0.6, max_el = 0.7, sl = function() return 3 end}, -- epic
  23. [8303] = {min_wl = 5, max_wl = 9, min_el = 0.8, max_el = 1, sl = function() return 4 end}, -- legendary
  24. [8305] = {min_wl = 0, max_wl = 9, min_el = 0.3, max_el = 1, sl = function() return math.random(2, 4) end} -- random
  25. },
  26.  
  27. maxSlotCount = 4,
  28. slotChances = {
  29. [1] = 1000,
  30. [2] = 5000,
  31. [3] = 15000,
  32. [4] = 25000
  33. },
  34. tiers = { -- item name based on slots looted (if more than 1)
  35. [2] = 'rare',
  36. [3] = 'epic',
  37. [4] = 'legendary'
  38. },
  39. weapon_levels = {
  40. -- weapon name if no slots were assigned, chance(1000 = 1%)
  41. [-9] = {'useless', 300},
  42. [-8] = {'broken', 500},
  43. [-7] = {'trash', 1000},
  44. [-6] = {'ruined', 1500},
  45. [-5] = {'damaged', 2000},
  46. [-4] = {'worthless', 2500},
  47. [-3] = {'blunt', 4000},
  48. [-2] = {'cheap', 7000},
  49. [-1] = {'common', 9000},
  50. [1] = {'uncommon', 25000},
  51. [2] = {'strengthened', 20000},
  52. [3] = {'fine', 15000},
  53. [4] = {'superior', 10000},
  54. [5] = {'rare', 7500},
  55. [6] = {'unique', 3500},
  56. [7] = {'flawless', 2500},
  57. [8] = {'epic', 1000},
  58. [9] = {'legendary', 500}
  59. },
  60. ignoredIds = {}, -- items with these ids will be banned from upgrading
  61. upgradeMagicItems = true, -- items with xml-sided bonuses, examples: magma coat, fire axe, boots of haste
  62. upgradeItemsWithNoArmor = true, -- allow upgrading clothes without arm value
  63. lootUpgradedItems = true,
  64. rare_popup = true,
  65. rare_text = "*rare*",
  66. rare_effect = true,
  67. rare_effect_id = CONST_ME_MAGIC_GREEN,
  68. rare_loot_level = true, -- set to false if you want to disable levels on looted weapons
  69. rare_negative_level = true, -- set to false if you want to disable it
  70. rare_min_level = -9,
  71.  
  72. useSkill = true, -- enchanting power based on player's skill, set to false if you want it random
  73. skillTriesStorage = 3866,
  74.  
  75. simple = { -- upgrade by jewels
  76. enabled = true,
  77. usePerks = false, -- unused
  78. randomSpells = true, -- todo: modal with selecting attr if false
  79. downgradeOnFail = true, -- item level only
  80. },
  81.  
  82. -- BASIC CONFIG ENDS HERE
  83. -- do not touch things below unless you are a advanced scripter
  84. skillFormula = function(lv) return math.ceil(((1 * lv^3) - (2 * lv^2) + (4 * lv)) / (90 + lv) + lv) end,
  85. maxLevel = 30,
  86.  
  87. levelUpgradeFormula = function(lv, minl)
  88. if STATS_SYSTEM_CONFIG.rare_negative_level then
  89. return math.ceil((lv/minl) * 25) + math.min(math.ceil(lv/minl * 5) +70, 75)
  90. else
  91. return 65 - math.ceil((lv/minl) * 3)
  92. end
  93. end,
  94.  
  95. -- spells and values for certain types of item
  96. UPGRADE_STATS_VALUES_PER_LVL = {
  97. -- value per level
  98. atk = 1,
  99. def = 1,
  100. extradef = 1,
  101. arm = 1,
  102. hitchance = 1,
  103. shootrange = 1
  104. },
  105.  
  106. UPGRADE_SPELLS = {
  107. necklace = {
  108. -- {'hp', 200, 10}, -- normal, percent
  109. -- {'mp', 300, 10},
  110. -- {'ml', 3, 6},
  111. -- {'melee', 2, 6},
  112. -- {'shield', 2, 6},
  113. -- {'dist', 2, 6},
  114. -- {'physical', 10, 5},
  115. -- {'energy', 10, 10},
  116. -- {'earth', 10, 10},
  117. -- {'fire', 10, 10},
  118. -- {'undefined', 10, 10},
  119. -- {'lifedrain', 10, 10},
  120. -- {'manadrain', 10, 10},
  121. -- {'healing', -10, -10},
  122. -- {'water', 20, 100},
  123. -- {'ice', 10, 10},
  124. -- {'holy', 10, 10},
  125. -- {'death', 10, 10},
  126. -- {'regHP', 5, 2}, -- normalhp, normalmp, percenthp, percentmp
  127. -- {'regMP', 10, 3}, -- normalhp, normalmp, percenthp, percentmp
  128. -- {'PVE death', 1, 100}
  129. },
  130. helmet = {
  131. {'ml', 2, 6},
  132. {'melee', 2, 6},
  133. {'dist', 2, 6},
  134. {'physical', 10, 3},
  135. {'energy', 10, 10},
  136. {'earth', 10, 10},
  137. {'fire', 10, 10},
  138. -- {'undefined', 10, 10},
  139. -- {'lifedrain', 10, 10},
  140. -- {'manadrain', 10, 10},
  141. -- {'healing', -10, -10},
  142. -- {'water', 20, 100},
  143. {'ice', 10, 10},
  144. {'holy', 10, 10},
  145. {'death', 10, 10},
  146. {'arm', 12, 70},
  147. },
  148. weapon = {
  149. {'melee', 3, 8},
  150. {'physical', 50, 10},
  151. {'energy', 50, 10},
  152. {'earth', 50, 10},
  153. {'fire', 50, 10},
  154. -- {'undefined', 50, 10},
  155. {'ice', 50, 10},
  156. {'holy', 50, 10},
  157. {'death', 50, 10},
  158. -- {'drainHP', 50, 3},
  159. -- {'drainMP', 50, 3},
  160. -- {'water', 50, 10},
  161. {'animals', 50, 10},
  162. {'humans', 50, 3},
  163. {'undeads', 50, 10},
  164. {'insects', 50, 10},
  165. {'atk', 6, 20},
  166. {'def', 10, 30},
  167. {'extra def', 10, 30},
  168. },
  169. distance = {
  170. {'dist', 3, 8},
  171. {'physical', 50, 10},
  172. {'energy', 50, 10},
  173. {'earth', 50, 10},
  174. {'fire', 50, 10},
  175. -- {'undefined', 50, 10},
  176. {'ice', 50, 10},
  177. {'holy', 50, 10},
  178. {'death', 50, 10},
  179. -- {'drainHP', 50, 3},
  180. -- {'drainMP', 50, 3},
  181. -- {'water', 50, 10},
  182. {'animals', 50, 10},
  183. {'humans', 50, 3},
  184. {'undeads', 50, 10},
  185. {'insects', 50, 10},
  186. {'atk', 6, 20},
  187. {'accuracy', 12, 70},
  188. {'range', 3, 50},
  189. },
  190. wand = {
  191. {'ml', 5, 15},
  192. {'physical', 100, 20},
  193. {'energy', 100, 20},
  194. {'earth', 100, 20},
  195. {'fire', 100, 20},
  196. -- {'undefined', 50, 10},
  197. {'healing', 50, 10},
  198. {'ice', 100, 20},
  199. {'holy', 100, 20},
  200. {'death', 100, 20},
  201. -- {'drainHP', 50, 3},
  202. -- {'drainMP', 50, 3},
  203. -- {'water', 50, 10},
  204. {'animals', 50, 10},
  205. {'humans', 50, 3},
  206. {'undeads', 50, 10},
  207. {'insects', 50, 10},
  208. {'range', 3, 50},
  209. },
  210. armor = {
  211. {'hp', 500, 15},
  212. {'mp', 800, 20},
  213. {'ml', 5, 7},
  214. {'melee', 5, 7},
  215. {'shield', 5, 7},
  216. {'dist', 5, 7},
  217. {'physical', 50, 5},
  218. {'energy', 10, 15},
  219. {'earth', 10, 15},
  220. {'fire', 10, 15},
  221. -- {'undefined', 10, 15},
  222. -- {'lifedrain', 10, 15},
  223. -- {'manadrain', 10, 15},
  224. -- {'healing', -10, -15},
  225. -- {'water', 20, 100},
  226. {'ice', 10, 15},
  227. {'holy', 10, 15},
  228. {'death', 10, 15},
  229. {'regHP', 5, 2},
  230. {'regMP', 10, 3},
  231. {'arm', 7, 30},
  232. },
  233. shield = {
  234. {'ml', 3, 10},
  235. {'shield', 5, 15},
  236. {'physical', 30, 5},
  237. {'energy', 10, 10},
  238. {'earth', 10, 10},
  239. {'fire', 10, 10},
  240. -- {'undefined', 10, 15},
  241. -- {'lifedrain', 10, 15},
  242. -- {'manadrain', 10, 15},
  243. {'ice', 10, 10},
  244. {'holy', 10, 10},
  245. {'death', 10, 10},
  246. {'regHP', 5, 2},
  247. {'regMP', 10, 3},
  248. {'def', 12, 30},
  249. },
  250. ring = {
  251. -- {'hp', 200, 10},
  252. -- {'mp', 300, 10},
  253. -- {'ml', 3, 6},
  254. -- {'melee', 3, 6},
  255. -- {'shield', 3, 6},
  256. -- {'dist', 3, 6},
  257. -- {'physical', 10, 5},
  258. -- {'energy', 10, 10},
  259. -- {'earth', 10, 10},
  260. -- {'fire', 10, 10},
  261. -- {'undefined', 10, 10},
  262. -- {'lifedrain', 10, 10},
  263. -- {'manadrain', 10, 10},
  264. -- {'healing', -10, -10},
  265. -- {'water', 20, 100},
  266. -- {'ice', 10, 10},
  267. -- {'holy', 10, 10},
  268. -- {'death', 10, 10},
  269. -- {'regHP', 5, 2},
  270. -- {'regMP', 10, 3},
  271. -- {'exp', 500, 30},
  272. },
  273. legs = {
  274. {'ml', 3, 6},
  275. {'melee', 3, 5},
  276. {'shield', 3, 5},
  277. {'dist', 3, 5},
  278. {'physical', 10, 4},
  279. {'energy', 10, 6},
  280. {'earth', 10, 6},
  281. {'fire', 10, 6},
  282. -- {'undefined', 10, 10},
  283. -- {'lifedrain', 10, 10},
  284. -- {'manadrain', 10, 10},
  285. -- {'healing', -10, -10},
  286. {'ice', 10, 6},
  287. {'holy', 10, 6},
  288. {'death', 10, 6},
  289. {'arm', 6, 40},
  290. },
  291. boots = {
  292. -- {'physical', 10, 3},
  293. -- {'energy', 10, 5},
  294. -- {'earth', 10, 5},
  295. -- {'fire', 10, 5},
  296. -- {'undefined', 10, 10},
  297. -- {'lifedrain', 10, 10},
  298. -- {'manadrain', 10, 10},
  299. -- {'healing', -10, -10},
  300. -- {'ice', 10, 5},
  301. -- {'holy', 10, 5},
  302. -- {'death', 10, 5},
  303. -- {'regHP', 8, 3},
  304. -- {'regMP', 15, 4},
  305. -- {'arm', 5, 50},
  306. },
  307. charges = {
  308. {'charges', 500, 45},
  309. },
  310. decay = {
  311. {'time', 1200000, 50},
  312. },
  313. },
  314.  
  315. STATS = {
  316. {
  317. name = 'hp',
  318.  
  319. weaponLootName = {'',''},
  320. armorLootName = {'','of improved health'},
  321. otherLootName = {'','of improved health'},
  322.  
  323. spellName = 'Health',
  324. enabledValues = true,
  325. enabledPercent = true
  326. },
  327.  
  328. {
  329. name = 'mp',
  330.  
  331. spellName = 'Mana',
  332. enabledValues = true,
  333.  
  334. weaponLootName = {'',''},
  335. armorLootName = {'','of improved mana'},
  336. otherLootName = {'','of improved mana'},
  337. enabledPercent = true
  338. },
  339.  
  340. {
  341. name = 'ml',
  342.  
  343. weaponLootName = {'magic',''},
  344. armorLootName = {'enchanted',''},
  345. otherLootName = {'magic',''},
  346.  
  347. spellName = 'Magic Level',
  348. enabledValues = true,
  349. enabledPercent = true
  350. },
  351.  
  352. {
  353. name = 'melee',
  354.  
  355. weaponLootName = {'','of power'},
  356. armorLootName = {'warrior',''},
  357. otherLootName = {'','of power'},
  358.  
  359. spellName = 'Melee Skill',
  360. enabledValues = true,
  361. enabledPercent = true
  362. },
  363.  
  364. {
  365. name = 'shield',
  366.  
  367. weaponLootName = {'','of defense'},
  368. armorLootName = {'fortified',''},
  369. otherLootName = {'','of defense'},
  370.  
  371. spellName = 'Shielding',
  372. enabledValues = true,
  373. enabledPercent = true
  374. },
  375.  
  376. {
  377. name = 'dist',
  378.  
  379. weaponLootName = {'','of hunting'},
  380. armorLootName = {'hunter',''},
  381. otherLootName = {'','of hunting'},
  382.  
  383. spellName = 'Distance Skill',
  384. enabledValues = true,
  385. enabledPercent = true
  386. },
  387.  
  388. -- element types
  389. -- on weapon: value = more or less element damage
  390. -- on armor: value = when something hits you, hit value may increase or decrease depending on value
  391. {
  392. name = 'physical',
  393. combatType = COMBAT_PHYSICALDAMAGE,
  394.  
  395. weaponLootName = {'','of bleeding'},
  396. armorLootName = {'strong',''},
  397. otherLootName = {'stone',''},
  398.  
  399. spellName = 'Physical',
  400. enabledValues = true,
  401. enabledPercent = true,
  402.  
  403. effect = CONST_ME_BLOCKHIT
  404. },
  405.  
  406.  
  407. {
  408. name = 'energy',
  409. combatType = COMBAT_ENERGYDAMAGE,
  410.  
  411. weaponLootName = {'','of thunders'},
  412. armorLootName = {'','of sparks'},
  413. otherLootName = {'','of lightning'},
  414.  
  415. oppositeSpell = 'earth', -- unused values
  416. spellName = 'Energy',
  417. enabledValues = true,
  418. enabledPercent = true,
  419.  
  420. effect = CONST_ME_ENERGYHIT
  421. },
  422.  
  423. {
  424. name = 'earth',
  425. combatType = COMBAT_EARTHDAMAGE,
  426.  
  427. weaponLootName = {'poison',''},
  428. armorLootName = {'earthproof',''},
  429. otherLootName = {'','of antidote'},
  430.  
  431. oppositeSpell = 'energy',
  432. spellName = 'Earth',
  433. enabledValues = true,
  434. enabledPercent = true,
  435. effect = CONST_ME_SMALLPLANTS
  436. },
  437.  
  438. {
  439. name = 'fire',
  440. combatType = COMBAT_FIREDAMAGE,
  441.  
  442. weaponLootName = {'burning',''},
  443. armorLootName = {'fireproof',''},
  444. otherLootName = {'','of fire protection'},
  445.  
  446. oppositeSpell = 'ice',
  447. spellName = 'Fire',
  448. enabledValues = true,
  449. enabledPercent = true,
  450. effect = CONST_ME_FIREATTACK
  451. },
  452.  
  453. {
  454. -- exist in tfs, not in use by default
  455. name = 'undefined',
  456. combatType = COMBAT_UNDEFINEDDAMAGE,
  457.  
  458. weaponLootName = {'ghost',''},
  459. armorLootName = {'',''},
  460. otherLootName = {'',''},
  461.  
  462. spellName = 'None',
  463. enabledValues = false,
  464. enabledPercent = false,
  465. effect = CONST_ME_GROUNDSHAKER
  466. },
  467.  
  468. {
  469. name = 'lifedrain',
  470. combatType = COMBAT_LIFEDRAIN,
  471.  
  472. weaponLootName = {'cursed',''},
  473. armorLootName = {'enchanted',''},
  474. otherLootName = {'blessed',''},
  475.  
  476. oppositeSpell = 'healing',
  477. spellName = 'Lifedrain',
  478. enabledValues = true,
  479. enabledPercent = true,
  480. effect = CONST_ME_MAGIC_RED
  481. },
  482.  
  483. {
  484. name = 'manadrain',
  485. combatType = COMBAT_MANADRAIN,
  486.  
  487. weaponLootName = {'','of dark magic'},
  488. armorLootName = {'sealed',''},
  489. otherLootName = {'','of mana protection'},
  490.  
  491. spellName = 'Manadrain',
  492. enabledValues = true,
  493. enabledPercent = true,
  494. effect = CONST_ME_LOSEENERGY
  495. },
  496.  
  497. {
  498. -- should not be used by weapons
  499. name = 'healing',
  500. combatType = COMBAT_HEALING,
  501.  
  502. weaponLootName = {'healer',''},
  503. armorLootName = {'','of healing'},
  504. otherLootName = {'','of healing'},
  505.  
  506. oppositeSpell = 'lifedrain',
  507. spellName = 'Healing',
  508. enabledValues = true,
  509. enabledPercent = true,
  510. effect = CONST_ME_MAGIC_BLUE
  511. },
  512.  
  513. {
  514. name = 'water',
  515. combatType = COMBAT_DROWNDAMAGE,
  516.  
  517. weaponLootName = {'','of fear'},
  518. armorLootName = {'','of the deep'},
  519. otherLootName = {'','of the deep'},
  520.  
  521. spellName = 'Water',
  522. enabledValues = true,
  523. enabledPercent = true,
  524. effect = CONST_ME_LOSEENERGY
  525. },
  526.  
  527. {
  528. name = 'ice',
  529. combatType = COMBAT_ICEDAMAGE,
  530.  
  531. weaponLootName = {'icy',''},
  532. armorLootName = {'frozen',''},
  533. otherLootName = {'','of cold'},
  534.  
  535. oppositeSpell = 'fire',
  536. spellName = 'Ice',
  537. enabledValues = true,
  538. enabledPercent = true,
  539. effect = CONST_ME_ICEATTACK
  540. },
  541.  
  542. {
  543. name = 'holy',
  544. combatType = COMBAT_HOLYDAMAGE,
  545.  
  546. weaponLootName = {'divine',''},
  547. armorLootName = {'','of darkness'},
  548. otherLootName = {'dark',''},
  549.  
  550. oppositeSpell = 'death',
  551. spellName = 'Holy',
  552. enabledValues = true,
  553. enabledPercent = true,
  554. effect = CONST_ME_HOLYDAMAGE
  555. },
  556.  
  557. {
  558. name = 'death',
  559. combatType = COMBAT_DEATHDAMAGE,
  560.  
  561. weaponLootName = {'','of darkness'},
  562. armorLootName = {'','of inquisition'},
  563. otherLootName = {'holy',''},
  564.  
  565. oppositeSpell = 'holy',
  566. spellName = 'Death',
  567. enabledValues = true,
  568. enabledPercent = true,
  569. effect = CONST_ME_MORTAREA
  570. },
  571.  
  572. -- weapon only
  573. {
  574. name = 'drainHP',
  575. drain = COMBAT_LIFEDRAIN,
  576.  
  577. weaponLootName = {'vampire',''},
  578. armorLootName = {'',''},
  579. otherLootName = {'',''},
  580.  
  581. spellName = 'Drain Health',
  582. enabledValues = true,
  583. enabledPercent = true
  584. },
  585.  
  586. {
  587. name = 'drainMP',
  588. drain = COMBAT_MANADRAIN,
  589.  
  590. weaponLootName = {'','of weakness'},
  591. armorLootName = {'',''},
  592. otherLootName = {'',''},
  593.  
  594. spellName = 'Drain Mana',
  595. enabledValues = true,
  596. enabledPercent = true
  597. },
  598.  
  599. {
  600. name = 'animals',
  601. weaponLootName = {'hunting',''},
  602. armorLootName = {'',''},
  603. otherLootName = {'',''},
  604. spellName = 'Animals',
  605. enabledValues = true,
  606. enabledPercent = true
  607. },
  608.  
  609. {
  610. name = 'humans',
  611.  
  612. weaponLootName = {'',''},
  613. armorLootName = {'',''},
  614. otherLootName = {'',''},
  615.  
  616. spellName = 'Humans',
  617. enabledValues = true,
  618. enabledPercent = true
  619. },
  620.  
  621. {
  622. name = 'undeads',
  623.  
  624. weaponLootName = {'','of inquisition'},
  625. armorLootName = {'',''},
  626. otherLootName = {'',''},
  627.  
  628. spellName = 'Undeads',
  629. enabledValues = true,
  630. enabledPercent = true
  631. },
  632.  
  633. {
  634. name = 'insects',
  635.  
  636. weaponLootName = {'','of insect hunting'},
  637. armorLootName = {'',''},
  638. otherLootName = {'',''},
  639.  
  640. spellName = 'Insects',
  641. enabledValues = true,
  642. enabledPercent = true
  643. },
  644.  
  645. -- buff
  646. {
  647. name = 'regHP',
  648.  
  649. weaponLootName = {'',''},
  650. armorLootName = {'','of vitality'},
  651. otherLootName = {'','of vitality'},
  652.  
  653. spellName = 'HP Regeneration',
  654. enabledValues = true,
  655. enabledPercent = true
  656. },
  657.  
  658. {
  659. name = 'regMP',
  660.  
  661. weaponLootName = {'',''},
  662. armorLootName = {'','of magic'},
  663. otherLootName = {'','of magic'},
  664.  
  665. spellName = 'MP Regeneration',
  666. enabledValues = true,
  667. enabledPercent = true
  668. },
  669.  
  670. -- attr based stats
  671. {
  672. name = 'charges',
  673.  
  674. weaponLootName = {'',''},
  675. armorLootName = {'',''},
  676. otherLootName = {'charged',''},
  677.  
  678. spellName = 'Charges',
  679. enabledValues = true,
  680. enabledPercent = true
  681. },
  682.  
  683. {
  684. name = 'time',
  685.  
  686. weaponLootName = {'',''},
  687. armorLootName = {'',''},
  688. otherLootName = {'fine',''},
  689.  
  690. spellName = 'Duration',
  691. enabledValues = true,
  692. enabledPercent = true
  693. },
  694.  
  695. {
  696. name = 'atk',
  697.  
  698. weaponLootName = {'sharpened',''},
  699. armorLootName = {'',''},
  700. otherLootName = {'',''},
  701.  
  702. spellName = 'Attack',
  703. enabledValues = true,
  704. enabledPercent = true
  705. },
  706.  
  707. {
  708. name = 'def',
  709.  
  710. weaponLootName = {'strong',''},
  711. armorLootName = {'fortified',''},
  712. otherLootName = {'',''},
  713.  
  714. spellName = 'Defense',
  715. enabledValues = true,
  716. enabledPercent = true
  717. },
  718.  
  719. {
  720. name = 'extra def',
  721.  
  722. weaponLootName = {'','of balance'},
  723. armorLootName = {'',''},
  724. otherLootName = {'',''},
  725.  
  726. spellName = 'Extra Defense',
  727. enabledValues = true,
  728. enabledPercent = true
  729. },
  730.  
  731. {
  732. name = 'arm',
  733.  
  734. weaponLootName = {'',''},
  735. armorLootName = {'masterpiece of',''},
  736. otherLootName = {'',''},
  737.  
  738. spellName = 'Armor',
  739. enabledValues = true,
  740. enabledPercent = true
  741. },
  742.  
  743. {
  744. name = 'accuracy',
  745.  
  746. weaponLootName = {'accurate',''},
  747. armorLootName = {'',''},
  748. otherLootName = {'',''},
  749.  
  750. spellName = 'Hit Chance',
  751. enabledValues = true, -- hit% + x%
  752. enabledPercent = true -- hit% + hit%*x%
  753. },
  754.  
  755. {
  756. name = 'range',
  757.  
  758. weaponLootName = {'sniper',''},
  759. armorLootName = {'',''},
  760. otherLootName = {'',''},
  761.  
  762. spellName = 'Range',
  763. enabledValues = true,
  764. enabledPercent = true
  765. },
  766.  
  767. {
  768. name = 'PVE death',
  769.  
  770. weaponLootName = {'',''},
  771. armorLootName = {'',''},
  772. otherLootName = {'','of good fate'},
  773.  
  774. spellName = 'PVE Death',
  775. enabledValues = true,
  776. enabledPercent = true
  777. },
  778. -- xp, loot
  779. {
  780. name = 'exp',
  781.  
  782. weaponLootName = {'',''},
  783. armorLootName = {'',''},
  784. otherLootName = {'','of experience'},
  785.  
  786. spellName = 'Extra Exp',
  787. enabledValues = true,
  788. enabledPercent = true
  789. },
  790.  
  791. {
  792. name = 'loot',
  793.  
  794. weaponLootName = {'',''},
  795. armorLootName = {'',''},
  796. otherLootName = {'','of luck'},
  797.  
  798. spellName = 'Luck',
  799. enabledValues = true,
  800. enabledPercent = true
  801. },
  802. },
  803. }
  804.  
  805. function getItemAttribute(uid, key, force)
  806. local i = ItemType(Item(uid):getId())
  807. local string_attributes = {
  808. [ITEM_ATTRIBUTE_NAME] = i:getName(),
  809. [ITEM_ATTRIBUTE_ARTICLE] = i:getArticle(),
  810. [ITEM_ATTRIBUTE_PLURALNAME] = i:getPluralName(),
  811. ["name"] = i:getName(),
  812. ["article"] = i:getArticle(),
  813. ["pluralname"] = i:getPluralName()
  814. }
  815.  
  816. local numeric_attributes = {
  817. [ITEM_ATTRIBUTE_WEIGHT] = i:getWeight(),
  818. [ITEM_ATTRIBUTE_ATTACK] = i:getAttack(),
  819. [ITEM_ATTRIBUTE_DEFENSE] = i:getDefense(),
  820. [ITEM_ATTRIBUTE_EXTRADEFENSE] = i:getExtraDefense(),
  821. [ITEM_ATTRIBUTE_ARMOR] = i:getArmor(),
  822. [ITEM_ATTRIBUTE_HITCHANCE] = i:getHitChance(),
  823. [ITEM_ATTRIBUTE_SHOOTRANGE] = i:getShootRange(),
  824. ["weight"] = i:getWeight(),
  825. ["attack"] = i:getAttack(),
  826. ["defense"] = i:getDefense(),
  827. ["extradefense"] = i:getExtraDefense(),
  828. ["armor"] = i:getArmor(),
  829. ["hitchance"] = i:getHitChance(),
  830. ["shootrange"] = i:getShootRange()
  831. }
  832.  
  833. local item = Item(uid)
  834. local attr = item:getAttribute(key)
  835. if tonumber(attr) then
  836. if numeric_attributes[key] then
  837. if force and item:getActionId() == 101 then
  838. return attr
  839. else
  840. return attr ~= 0 and attr or numeric_attributes[key]
  841. end
  842. end
  843. else
  844. if string_attributes[key] then
  845. if attr == "" then
  846. return string_attributes[key]
  847. end
  848. end
  849. end
  850. return attr
  851. end
  852.  
  853. function doItemSetAttribute(uid, key, value)
  854. return Item(uid):setAttribute(key, value)
  855. end
  856.  
  857. function doItemEraseAttribute(uid, key)
  858. return Item(uid):removeAttribute(key)
  859. end
  860.  
  861. local element_stats = {}
  862. local drain_stats = {}
  863.  
  864. for i = 1, #STATS_SYSTEM_CONFIG.STATS do
  865. local stat = STATS_SYSTEM_CONFIG.STATS[i]
  866. if stat.drain then
  867. drain_stats[stat.name] = stat.drain
  868. end
  869.  
  870. if stat.combatType then
  871. element_stats[stat.name] = {combat = stat.combatType, effect = stat.effect}
  872. end
  873. end
  874.  
  875. local stat_conditions = {
  876. [1] = {['hp'] = {}, ['mp'] = {}, ['ml'] = {}, ['melee'] = {}, ['shield'] = {}, ['dist'] = {}}, -- normal
  877. [2] = {['hp'] = {}, ['mp'] = {}, ['ml'] = {}, ['melee'] = {}, ['shield'] = {}, ['dist'] = {}} -- percent
  878. }
  879.  
  880. for i = -95, 300 do
  881. -- % stats and skills
  882. stat_conditions[2]['hp'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  883. setConditionParam(stat_conditions[2]['hp'][i], CONDITION_PARAM_SUBID, 50)
  884. setConditionParam(stat_conditions[2]['hp'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  885. setConditionParam(stat_conditions[2]['hp'][i], CONDITION_PARAM_TICKS, -1)
  886. setConditionParam(stat_conditions[2]['hp'][i], CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT, 100+i)
  887.  
  888. stat_conditions[2]['mp'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  889. setConditionParam(stat_conditions[2]['mp'][i], CONDITION_PARAM_SUBID, 51)
  890. setConditionParam(stat_conditions[2]['mp'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  891. setConditionParam(stat_conditions[2]['mp'][i], CONDITION_PARAM_TICKS, -1)
  892. setConditionParam(stat_conditions[2]['mp'][i], CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT, 100+i)
  893.  
  894. stat_conditions[2]['ml'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  895. setConditionParam(stat_conditions[2]['ml'][i], CONDITION_PARAM_SUBID, 52)
  896. setConditionParam(stat_conditions[2]['ml'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  897. setConditionParam(stat_conditions[2]['ml'][i], CONDITION_PARAM_TICKS, -1)
  898. setConditionParam(stat_conditions[2]['ml'][i], CONDITION_PARAM_STAT_MAGICPOINTSPERCENT, 100+i)
  899.  
  900. stat_conditions[2]['melee'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  901. setConditionParam(stat_conditions[2]['melee'][i], CONDITION_PARAM_SUBID, 53)
  902. setConditionParam(stat_conditions[2]['melee'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  903. setConditionParam(stat_conditions[2]['melee'][i], CONDITION_PARAM_TICKS, -1)
  904. setConditionParam(stat_conditions[2]['melee'][i], CONDITION_PARAM_SKILL_MELEEPERCENT, 100+i)
  905.  
  906. stat_conditions[2]['shield'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  907. setConditionParam(stat_conditions[2]['shield'][i], CONDITION_PARAM_SUBID, 54)
  908. setConditionParam(stat_conditions[2]['shield'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  909. setConditionParam(stat_conditions[2]['shield'][i], CONDITION_PARAM_TICKS, -1)
  910. setConditionParam(stat_conditions[2]['shield'][i], CONDITION_PARAM_SKILL_SHIELDPERCENT, 100+i)
  911.  
  912. stat_conditions[2]['dist'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  913. setConditionParam(stat_conditions[2]['dist'][i], CONDITION_PARAM_SUBID, 55)
  914. setConditionParam(stat_conditions[2]['dist'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  915. setConditionParam(stat_conditions[2]['dist'][i], CONDITION_PARAM_TICKS, -1)
  916. setConditionParam(stat_conditions[2]['dist'][i], CONDITION_PARAM_SKILL_DISTANCEPERCENT, 100+i)
  917. end
  918.  
  919. for i = -1500, 1500 do
  920. -- hp mp normal
  921. stat_conditions[1]['hp'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  922. setConditionParam(stat_conditions[1]['hp'][i], CONDITION_PARAM_SUBID, 56)
  923. setConditionParam(stat_conditions[1]['hp'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  924. setConditionParam(stat_conditions[1]['hp'][i], CONDITION_PARAM_TICKS, -1)
  925. setConditionParam(stat_conditions[1]['hp'][i], CONDITION_PARAM_STAT_MAXHITPOINTS, i)
  926.  
  927. stat_conditions[1]['mp'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  928. setConditionParam(stat_conditions[1]['mp'][i], CONDITION_PARAM_SUBID, 57)
  929. setConditionParam(stat_conditions[1]['mp'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  930. setConditionParam(stat_conditions[1]['mp'][i], CONDITION_PARAM_TICKS, -1)
  931. setConditionParam(stat_conditions[1]['mp'][i], CONDITION_PARAM_STAT_MAXMANAPOINTS, i)
  932. end
  933.  
  934. for i = -100, 100 do
  935. -- skills
  936. stat_conditions[1]['ml'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  937. setConditionParam(stat_conditions[1]['ml'][i], CONDITION_PARAM_SUBID, 58)
  938. setConditionParam(stat_conditions[1]['ml'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  939. setConditionParam(stat_conditions[1]['ml'][i], CONDITION_PARAM_TICKS, -1)
  940. setConditionParam(stat_conditions[1]['ml'][i], CONDITION_PARAM_STAT_MAGICPOINTS, i)
  941.  
  942. stat_conditions[1]['melee'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  943. setConditionParam(stat_conditions[1]['melee'][i], CONDITION_PARAM_SUBID, 59)
  944. setConditionParam(stat_conditions[1]['melee'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  945. setConditionParam(stat_conditions[1]['melee'][i], CONDITION_PARAM_TICKS, -1)
  946. setConditionParam(stat_conditions[1]['melee'][i], CONDITION_PARAM_SKILL_MELEE, i)
  947.  
  948. stat_conditions[1]['shield'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  949. setConditionParam(stat_conditions[1]['shield'][i], CONDITION_PARAM_SUBID, 60)
  950. setConditionParam(stat_conditions[1]['shield'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  951. setConditionParam(stat_conditions[1]['shield'][i], CONDITION_PARAM_TICKS, -1)
  952. setConditionParam(stat_conditions[1]['shield'][i], CONDITION_PARAM_SKILL_SHIELD, i)
  953.  
  954. stat_conditions[1]['dist'][i] = createConditionObject(CONDITION_ATTRIBUTES)
  955. setConditionParam(stat_conditions[1]['dist'][i], CONDITION_PARAM_SUBID, 61)
  956. setConditionParam(stat_conditions[1]['dist'][i], CONDITION_PARAM_BUFF_SPELL, 1)
  957. setConditionParam(stat_conditions[1]['dist'][i], CONDITION_PARAM_TICKS, -1)
  958. setConditionParam(stat_conditions[1]['dist'][i], CONDITION_PARAM_SKILL_DISTANCE, i)
  959. end
  960.  
  961. local magic_words = { -- see upgradeMagicItems in config
  962. 'physical',
  963. 'fire',
  964. 'ice',
  965. 'earth',
  966. 'energy',
  967. 'poison',
  968. 'drown',
  969. 'holy',
  970. 'death',
  971. 'lifedrain',
  972. 'manadrain',
  973. 'protection',
  974. 'magic',
  975. 'fighting',
  976. 'shielding',
  977. 'speed',
  978. 'invisibility',
  979. 'drinking',
  980. 'regeneration',
  981. }
  982.  
  983. local upgrade_types = {
  984. none = false,
  985. necklace = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.necklace,
  986. helmet = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.helmet,
  987. weapon = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.weapon,
  988. distance = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.distance,
  989. wand = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.wand,
  990. armor = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.armor,
  991. shield = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.shield,
  992. ring = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.ring,
  993. legs = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.legs,
  994. boots = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.boots,
  995. charges = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.charges,
  996. decay = STATS_SYSTEM_CONFIG.UPGRADE_SPELLS.decay,
  997. }
  998.  
  999. function Item:getUpgradeType()
  1000. local it_id = self:getType()
  1001. if it_id:isStackable() or it_id:isContainer() then
  1002. return upgrade_types.none
  1003. end
  1004.  
  1005. local wp = it_id:getWeaponType()
  1006. if self:getAttribute(ITEM_ATTRIBUTE_CHARGES) > 0 then
  1007. if wp > 0 then
  1008. return upgrade_types.none
  1009. end
  1010. return upgrade_types.charges
  1011. end
  1012.  
  1013. if self:getAttribute(ITEM_ATTRIBUTE_DURATION) > 0 then
  1014. if wp > 0 then
  1015. return upgrade_types.none
  1016. end
  1017. return upgrade_types.decay
  1018. else
  1019. if self:getBaseDuration() > 0 then
  1020. if wp > 0 then
  1021. return upgrade_types.none
  1022. end
  1023. return upgrade_types.decay
  1024. end
  1025. end
  1026.  
  1027. if wp > 0 then
  1028. if wp == WEAPON_SHIELD then
  1029. return upgrade_types.shield
  1030. elseif wp == WEAPON_DISTANCE then
  1031. return upgrade_types.distance
  1032. elseif wp == WEAPON_WAND then
  1033. return upgrade_types.wand
  1034. elseif isInArray({WEAPON_SWORD, WEAPON_CLUB, WEAPON_AXE}, wp) then
  1035. return upgrade_types.weapon
  1036. end
  1037. else
  1038. local slot = it_id:getSlotPosition() - SLOTP_LEFT - SLOTP_RIGHT
  1039. if it_id:getArmor() > 0 or STATS_SYSTEM_CONFIG.upgradeItemsWithNoArmor then
  1040. if slot == SLOTP_HEAD then
  1041. return upgrade_types.helmet
  1042. elseif slot == SLOTP_ARMOR then
  1043. return upgrade_types.armor
  1044. elseif slot == SLOTP_LEGS then
  1045. return upgrade_types.legs
  1046. elseif slot == SLOTP_FEET then
  1047. return upgrade_types.boots
  1048. end
  1049. end
  1050.  
  1051. if slot == SLOTP_NECKLACE then
  1052. return upgrade_types.necklace
  1053. end
  1054.  
  1055. if slot == SLOTP_RING then
  1056. return upgrade_types.ring
  1057. end
  1058. end
  1059.  
  1060. return upgrade_types.none
  1061. end
  1062.  
  1063. function Item:getStatSlotCount()
  1064. local c = 0
  1065. for _ in self:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION):gmatch('%[(.-)%]') do
  1066. c = c+1
  1067. end
  1068. return c
  1069. end
  1070.  
  1071. function Item:getStatSlots()
  1072. local t = {}
  1073. for _ in self:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION):gmatch('(%[.-%])') do
  1074. if _ then
  1075. if _:match('%[(.+)%]') then
  1076. local n = _:match('%[(.+)%]')
  1077. if n ~= '?' then
  1078. local n1 = n:split(".")
  1079. local i = #t + 1
  1080. t[i] = {n1[1], n1[2]}
  1081. end
  1082. end
  1083. end
  1084. end
  1085. return t
  1086. end
  1087.  
  1088. function Item:addStatSlot(spell, val, suffix)
  1089. if spell and val then
  1090. if not suffix then suffix = "" end
  1091. self:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, self:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION) .. "[" .. spell .. "." .. (val >= 0 and "+" .. val or val) .. suffix .. "]")
  1092. else
  1093. return false
  1094. end
  1095. return true
  1096. end
  1097.  
  1098. function Item:addSlot(name, val, percent)
  1099. val = tonumber(val)
  1100. if name and val then
  1101. if self:addStat(name, val, (percent and "%" or "")) then
  1102. return true
  1103. end
  1104. end
  1105. return false
  1106. end
  1107.  
  1108. function Item:getBaseDuration()
  1109. local it_id = self:getId()
  1110. local tid = ItemType(it_id):getTransformEquipId()
  1111. local vx = self:getAttribute(ITEM_ATTRIBUTE_DURATION)
  1112.  
  1113. if tid > 0 then
  1114. self:transform(tid)
  1115. vx = self:getAttribute(ITEM_ATTRIBUTE_DURATION)
  1116. self:transform(it_id)
  1117. self:removeAttribute(ITEM_ATTRIBUTE_DURATION)
  1118. end
  1119. return vx
  1120. end
  1121.  
  1122. function Item:getBaseStatsInfo()
  1123. local it_id = self:getType()
  1124. local t = {
  1125. attack = it_id:getAttack(),
  1126. defense = it_id:getDefense(),
  1127. extraDefense = it_id:getExtraDefense(),
  1128. armor = it_id:getArmor(),
  1129. hitChance = it_id:getHitChance(),
  1130. shootRange = it_id:getShootRange(),
  1131. charges = it_id:getCharges(),
  1132. duration = self:getBaseDuration()
  1133. }
  1134. return t
  1135. end
  1136.  
  1137. function getEnchantingSkill(tries)
  1138. local xp = 0
  1139. local level = 0
  1140. for lv = 1, STATS_SYSTEM_CONFIG.maxLevel do
  1141. xp = STATS_SYSTEM_CONFIG.skillFormula(lv) -- alternative: xp = xp + STATS_SYSTEM_CONFIG.skillFormula(lv)
  1142. if tries < xp then
  1143. level = lv
  1144. break
  1145. end
  1146. level = lv
  1147. end
  1148. return level
  1149. end
  1150.  
  1151. local SPELL_TYPE_VALUE = 1
  1152. local SPELL_TYPE_PERCENT = 2
  1153. local attrkeys = {
  1154. ['charges'] = ITEM_ATTRIBUTE_CHARGES,
  1155. ['time'] = ITEM_ATTRIBUTE_DURATION,
  1156. ['atk'] = ITEM_ATTRIBUTE_ATTACK,
  1157. ['def'] = ITEM_ATTRIBUTE_DEFENSE,
  1158. ['extra def'] = ITEM_ATTRIBUTE_EXTRADEFENSE,
  1159. ['arm'] = ITEM_ATTRIBUTE_ARMOR,
  1160. ['accuracy'] = ITEM_ATTRIBUTE_HITCHANCE,
  1161. ['range'] = ITEM_ATTRIBUTE_SHOOTRANGE
  1162. }
  1163.  
  1164. function Item.addStat(item, spellname, spellvalue, suffix, cid)
  1165. if isInArray({'charges', 'time', 'atk', 'def', 'extra def', 'arm', 'accuracy', 'range'}, spellname) then
  1166. local basestats = item:getBaseStatsInfo()
  1167. local basestats2 = {
  1168. ['charges'] = basestats.charges,
  1169. ['time'] = basestats.duration,
  1170. ['atk'] = basestats.attack,
  1171. ['def'] = basestats.defense,
  1172. ['extra def'] = basestats.extraDefense,
  1173. ['arm'] = basestats.armor,
  1174. ['accuracy'] = basestats.hitChance,
  1175. ['range'] = basestats.shootRange
  1176. }
  1177.  
  1178. local uid = item:getUniqueId()
  1179. local fullstats = {
  1180. ['charges'] = getItemAttribute(uid, ITEM_ATTRIBUTE_CHARGES),
  1181. ['time'] = item:getBaseDuration(),
  1182. ['atk'] = getItemAttribute(uid, ITEM_ATTRIBUTE_ATTACK),
  1183. ['def'] = getItemAttribute(uid, ITEM_ATTRIBUTE_DEFENSE),
  1184. ['extra def'] = getItemAttribute(uid, ITEM_ATTRIBUTE_EXTRADEFENSE),
  1185. ['arm'] = getItemAttribute(uid, ITEM_ATTRIBUTE_ARMOR),
  1186. ['accuracy'] = getItemAttribute(uid, ITEM_ATTRIBUTE_HITCHANCE),
  1187. ['range'] = getItemAttribute(uid, ITEM_ATTRIBUTE_SHOOTRANGE)
  1188. }
  1189.  
  1190.  
  1191. if suffix == "%" then
  1192. if basestats2[spellname] == 0 then
  1193. if cid then
  1194. Player(cid):sendTextMessage(MESSAGE_INFO_DESCR, "Spell " .. spellname .. "% is not available for this item.")
  1195. end
  1196. return false
  1197. end
  1198. item:setAttribute(attrkeys[spellname], fullstats[spellname] + math.abs(math.floor((basestats2[spellname] * spellvalue/100)))) -- basestat intended to prevent too high values when combined with upgrade system
  1199. else
  1200. item:setAttribute(attrkeys[spellname], fullstats[spellname] + math.abs(spellvalue))
  1201. end
  1202. end
  1203. item:addStatSlot(spellname, spellvalue, suffix)
  1204. return true
  1205. end
  1206.  
  1207. local upgradable_stats = {
  1208. [1] = {ITEM_ATTRIBUTE_ATTACK, function(id) return id:getAttack() end, STATS_SYSTEM_CONFIG.UPGRADE_STATS_VALUES_PER_LVL.atk},
  1209. [2] = {ITEM_ATTRIBUTE_DEFENSE, function(id) return id:getDefense() end, STATS_SYSTEM_CONFIG.UPGRADE_STATS_VALUES_PER_LVL.def},
  1210. [3] = {ITEM_ATTRIBUTE_EXTRADEFENSE, function(id) return id:getExtraDefense() end, STATS_SYSTEM_CONFIG.UPGRADE_STATS_VALUES_PER_LVL.extradef},
  1211. [4] = {ITEM_ATTRIBUTE_ARMOR, function(id) return id:getArmor() end, STATS_SYSTEM_CONFIG.UPGRADE_STATS_VALUES_PER_LVL.arm},
  1212. [5] = {ITEM_ATTRIBUTE_HITCHANCE, function(id) return id:getHitChance() end, STATS_SYSTEM_CONFIG.UPGRADE_STATS_VALUES_PER_LVL.hitchance},
  1213. [6] = {ITEM_ATTRIBUTE_SHOOTRANGE, function(id) return id:getShootRange() > 1 and id:getShootRange() or 0 end, STATS_SYSTEM_CONFIG.UPGRADE_STATS_VALUES_PER_LVL.shootrange}
  1214. }
  1215.  
  1216. function stat_onUse(player, item, fromPosition, itemEx, toPosition, attempt)
  1217. if item.itemid == STATS_SYSTEM_CONFIG.GEM_BASIC_LEVEL then
  1218. if STATS_SYSTEM_CONFIG.addLevelAction then
  1219. local it_id = ItemType(itemEx.itemid)
  1220. if it_id then
  1221. if not it_id:isStackable() then
  1222. if it_id:getTransformEquipId() < 1 then
  1223. if it_id:getCharges() < 1 then
  1224. local item_sp_slot = it_id:getSlotPosition() - SLOTP_LEFT - SLOTP_RIGHT
  1225. if item_sp_slot ~= SLOTP_NECKLACE and item_sp_slot ~= SLOTP_RING and (item_sp_slot > 0 or it_id:getWeaponType() > 0) then
  1226. local stat_min = 1
  1227. if STATS_SYSTEM_CONFIG.rare_negative_level then
  1228. stat_min = STATS_SYSTEM_CONFIG.rare_min_level
  1229. end
  1230.  
  1231. local stat_max = #STATS_SYSTEM_CONFIG.weapon_levels
  1232. local stat_lvl = tonumber(getItemAttribute(itemEx.uid, ITEM_ATTRIBUTE_NAME):match("%s%+%d+") or getItemAttribute(itemEx.uid, ITEM_ATTRIBUTE_NAME):match("%s%-%d+"))
  1233. if stat_lvl == stat_max then
  1234. player:sendTextMessage(MESSAGE_INFO_DESCR, "This item is on max level already.")
  1235. return true
  1236. end
  1237.  
  1238. local n_lvl = stat_lvl
  1239. if not stat_lvl then
  1240. stat_lvl = 0
  1241. end
  1242.  
  1243. local chance = STATS_SYSTEM_CONFIG.levelUpgradeFormula(stat_lvl, stat_min)
  1244. local it_u = Item(itemEx.uid)
  1245. local it_name = it_u:getName()
  1246. if stat_lvl > 0 then
  1247. it_name = getItemAttribute(itemEx.uid, ITEM_ATTRIBUTE_NAME):split("+")[1]
  1248. elseif stat_lvl < 0 then
  1249. it_name = getItemAttribute(itemEx.uid, ITEM_ATTRIBUTE_NAME):split("-")[1]
  1250. end
  1251.  
  1252. it_name = it_name:gsub("^%s*(.-)%s*$", "%1")
  1253.  
  1254. if math.random(1, 100) <= chance then
  1255. n_lvl = stat_lvl + 1
  1256. else
  1257. if STATS_SYSTEM_CONFIG.simple.downgradeOnFail then
  1258. n_lvl = stat_lvl - 1
  1259. end
  1260. end
  1261.  
  1262. for i = 1, #upgradable_stats do
  1263. local n_item_stat = upgradable_stats[i][2](it_id)
  1264. it_u:setAttribute(upgradable_stats[i][1], getItemAttribute(itemEx.uid, upgradable_stats[i][1], true) + (upgradable_stats[i][3] * (n_lvl - stat_lvl)))
  1265. end
  1266.  
  1267. it_u:setActionId(101)
  1268. Item(item.uid):remove(1)
  1269. if (n_lvl - stat_lvl) > 0 then
  1270. player:sendTextMessage(MESSAGE_INFO_DESCR, it_name:gsub("^%l", string.upper) .. " upgraded to " .. (n_lvl > 0 and "+" or "") .. n_lvl .. ".")
  1271. toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN)
  1272. else
  1273. player:sendTextMessage(MESSAGE_INFO_DESCR, "Attempt to upgrade failed.")
  1274. toPosition:sendMagicEffect(CONST_ME_HITAREA)
  1275. end
  1276.  
  1277. it_u:setAttribute(ITEM_ATTRIBUTE_NAME, it_name .. (n_lvl ~= 0 and (" " .. (n_lvl > 0 and "+" or "") .. n_lvl) or ""))
  1278. return true
  1279. end
  1280. end
  1281. end
  1282. end
  1283. end
  1284. end
  1285. return false
  1286. end
  1287.  
  1288. if item.itemid == STATS_SYSTEM_CONFIG.GEM_ADD_SLOT then
  1289. if not STATS_SYSTEM_CONFIG.addSlotAction then
  1290. return false
  1291. end
  1292.  
  1293. if not attempt then
  1294. attempt = 1
  1295. end
  1296.  
  1297. if attempt == 10 then
  1298. player:sendTextMessage(MESSAGE_INFO_DESCR, "Unable to add slot.")
  1299. return true
  1300. end
  1301.  
  1302. local it_u = Item(itemEx.uid)
  1303. if not it_u then
  1304. return false
  1305. end
  1306.  
  1307. if not STATS_SYSTEM_CONFIG.simple.enabled then
  1308. return false
  1309. end
  1310.  
  1311. if not STATS_SYSTEM_CONFIG.simple.randomSpells then
  1312. -- popup modal
  1313. -- popUpStatModal_index(player, item.uid)
  1314. print("todo: modal window")
  1315. return true
  1316. end
  1317.  
  1318. if isInArray(STATS_SYSTEM_CONFIG.ignoredIds, itemEx.itemid) then
  1319. -- player:sendTextMessage(MESSAGE_INFO_DESCR, "You cannot upgrade this item.")
  1320. return false
  1321. end
  1322.  
  1323. local it_id = ItemType(itemEx.itemid)
  1324. local u = it_u:getUpgradeType()
  1325.  
  1326. if not u then
  1327. -- player:sendTextMessage(MESSAGE_INFO_DESCR, "You cannot upgrade this item.")
  1328. return false
  1329. end
  1330.  
  1331. if not STATS_SYSTEM_CONFIG.upgradeMagicItems then
  1332. local atr = it_u:getDescription():match('%((.+)%)')
  1333. if atr and magic_words then
  1334. if #magic_words > 0 then
  1335. for i = 1, #magic_words do
  1336. if atr:match(magic_words[i]) then
  1337. player:sendTextMessage(MESSAGE_INFO_DESCR, "You cannot upgrade magic items.")
  1338. return true
  1339. end
  1340. end
  1341. end
  1342. end
  1343. end
  1344.  
  1345. local stat = math.random(1, #u)
  1346.  
  1347. local tries = player:getStorageValue(STATS_SYSTEM_CONFIG.skillTriesStorage)
  1348. if tries < 0 then
  1349. player:setStorageValue(STATS_SYSTEM_CONFIG.skillTriesStorage, 0)
  1350. end
  1351.  
  1352. local level = STATS_SYSTEM_CONFIG.useSkill and getEnchantingSkill(tries) or math.random(1, STATS_SYSTEM_CONFIG.maxLevel)
  1353.  
  1354. local spellname = u[stat][1]
  1355. local spelltype = 0
  1356. local available_spell_types = {}
  1357.  
  1358. for i = 1, #STATS_SYSTEM_CONFIG.STATS do
  1359. if STATS_SYSTEM_CONFIG.STATS[i].name == spellname then
  1360. if STATS_SYSTEM_CONFIG.STATS[i].enabledValues then
  1361. table.insert(available_spell_types, SPELL_TYPE_VALUE)
  1362. end
  1363.  
  1364. if STATS_SYSTEM_CONFIG.STATS[i].enabledPercent then
  1365. table.insert(available_spell_types, SPELL_TYPE_PERCENT)
  1366. end
  1367.  
  1368. if #available_spell_types > 0 then
  1369. spelltype = available_spell_types[math.random(1, #available_spell_types)]
  1370. end
  1371. break
  1372. end
  1373. end
  1374.  
  1375. if spelltype == 0 then
  1376. player:sendTextMessage(MESSAGE_INFO_DESCR, "Error: spell is unavailable.")
  1377. return true
  1378. end
  1379.  
  1380. local spellattr = nil
  1381. for i = 1, #STATS_SYSTEM_CONFIG.STATS do
  1382. if STATS_SYSTEM_CONFIG.STATS[i].name == spellname then
  1383. spellattr = STATS_SYSTEM_CONFIG.STATS[i]
  1384. break
  1385. end
  1386. end
  1387.  
  1388. if not spellattr then
  1389. player:sendTextMessage(MESSAGE_INFO_DESCR, "Error: spell is unavailable.")
  1390. return true
  1391. end
  1392.  
  1393. local prc = (level * 100/STATS_SYSTEM_CONFIG.maxLevel)/100
  1394. local attrval = 0
  1395. local attrstr = ""
  1396.  
  1397. if spelltype == SPELL_TYPE_VALUE then
  1398. attrval = math.floor(prc * u[stat][2])
  1399. elseif spelltype == SPELL_TYPE_PERCENT then
  1400. attrval = math.floor(prc * u[stat][3])
  1401. attrstr = "%"
  1402. end
  1403.  
  1404. if attrval == 0 then
  1405. player:sendTextMessage(MESSAGE_INFO_DESCR, "Error: spell is unavailable.")
  1406. return true
  1407. end
  1408.  
  1409. local slotc = it_u:getStatSlotCount()
  1410. if slotc == STATS_SYSTEM_CONFIG.maxSlotCount then
  1411. player:sendTextMessage(MESSAGE_INFO_DESCR, "Slot limit reached.")
  1412. return true
  1413. end
  1414.  
  1415. local cur_slots = it_u:getStatSlots()
  1416. for i = 1, slotc do
  1417. if spellname == cur_slots[i][1] then
  1418. -- player:sendTextMessage(MESSAGE_INFO_DESCR, "Duplicate stat, try again.")
  1419. stat_onUse(player, item, fromPosition, itemEx, toPosition, attempt + 1)
  1420. return true
  1421. end
  1422. end
  1423.  
  1424. if it_u:addStat(spellname, attrval, attrstr, player:getId()) then
  1425. toPosition:sendMagicEffect(CONST_ME_MAGIC_GREEN)
  1426. player:sendTextMessage(MESSAGE_INFO_DESCR, "Upgrade successful.\n" .. spellattr.spellName .. " " .. (attrval >= 0 and "+" .. attrval or attrval) .. attrstr)
  1427. doRemoveItem(item.uid, 1)
  1428. if STATS_SYSTEM_CONFIG.useSkill then
  1429. player:setStorageValue(STATS_SYSTEM_CONFIG.skillTriesStorage, player:getStorageValue(STATS_SYSTEM_CONFIG.skillTriesStorage) + 1)
  1430. local nlevel = STATS_SYSTEM_CONFIG.useSkill and getEnchantingSkill(player:getStorageValue(STATS_SYSTEM_CONFIG.skillTriesStorage)) or math.random(1, STATS_SYSTEM_CONFIG.maxLevel)
  1431. if nlevel > level then
  1432. player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You advanced to enchanting Level " .. (nlevel < STATS_SYSTEM_CONFIG.maxLevel and nlevel or nlevel .. " [max]") .. ".")
  1433. end
  1434. end
  1435. end
  1436. return true
Add Comment
Please, Sign In to add comment