2.4.3. addon, shows better gear by slot and stat type
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.

238 lines
7.6KB

  1. ;; init note
  2. (if (> 1 (# itemdb))
  3. (print "Failed to load item database")
  4. (print "Item database loaded"))
  5. ;; 1a: coll utils
  6. (fn length-of [coll]
  7. (if coll
  8. (do
  9. (var c 0)
  10. (each [k (pairs coll)]
  11. (set c (+ c 1)))
  12. c)
  13. 0))
  14. (fn first [coll]
  15. (let [key (next coll)]
  16. (. coll key)))
  17. ;; 1b: str utils
  18. (fn starts-with [s patt]
  19. (= (string.sub s 1 (string.len patt)) patt))
  20. (fn un-quote [s]
  21. (string.gsub s "\'" ""))
  22. ;; 1c: number utils
  23. (fn max [a b]
  24. (if (> a b) a b))
  25. ;; 1d: fennel utils
  26. (fn matches [a b]
  27. (if (starts-with a "lte:")
  28. (>= (tonumber (string.sub a 5)) (tonumber b))
  29. (starts-with a "gte:")
  30. (<= (tonumber (string.sub a 5)) (tonumber b))
  31. (starts-with a "lt<:")
  32. (> (tonumber (string.sub a 5)) (tonumber b))
  33. (starts-with a "gt>:")
  34. (< (tonumber (string.sub a 5)) (tonumber b))
  35. (= a b)))
  36. ;; 2a: querying
  37. (lambda find-items [params ?sort]
  38. (let [results (icollect [_ row (ipairs itemdb)]
  39. (do
  40. (var hit true)
  41. (each [key param (pairs params)]
  42. (do
  43. (set hit (and hit (matches param (. row key))))))
  44. (if hit
  45. row)))]
  46. (if (and ?sort results)
  47. (do
  48. (table.sort results ?sort)
  49. results)
  50. results)))
  51. (lambda find-item [params ?sort]
  52. (let [results (find-items params ?sort)]
  53. (if results
  54. (. results 1))))
  55. ;; 2b: specialized querying
  56. (fn find-item-by-name [name]
  57. (find-item {8 name}))
  58. (fn find-next-better-item [class subclass invtype lv ilv stat-position item-stat ?sort]
  59. (find-items {4 class
  60. 6 subclass
  61. 10 invtype
  62. 14 (string.format "gte:%d" (- lv 4))
  63. 14 (string.format "lte:%d" lv)
  64. ;; 12 (string.format "gte:%d" ilv)
  65. stat-position (string.format "gt>:%d" item-stat)}
  66. ?sort))
  67. (lambda find-good-item [invtype lv stat-position stat-baseline ?sort]
  68. (find-items {10 invtype
  69. 14 (string.format "gte:%d" (- lv 6))
  70. 14 (string.format "lte:%d" lv)
  71. stat-position (string.format "gte:%d" stat-baseline)}
  72. ?sort))
  73. ;; 3b: specialized parsing
  74. (fn parse-item-id [link]
  75. (tonumber (string.sub (string.match link "item:[%d+]+") 6)))
  76. ;; 3c: arg parsing
  77. (fn parse-opts [msg]
  78. (icollect [k v (string.gmatch msg "%w+")] v))
  79. ;; 4a: ui
  80. (fn ui-print [msg]
  81. (UIErrorsFrame:AddMessage msg))
  82. ;; 4b
  83. (fn stat-name [n]
  84. (let [stat-names ["Mana" "Health" "No Visible Effect"
  85. "Agility" "Strength" "Intellect"
  86. "Spirit" "Stamina" "No Visible Effect" "No Visible Effect"
  87. "No Visible Effect" "No Visible Effect*" "Defense Rating"
  88. "Dodge" "Parry Rating" "Shield Block Rating"
  89. "Melee Hit Rating" "Ranged Hit Rating" "Spell Hit Rating"
  90. "Melee Critical Strike" "Ranged Critical Strike" "Spell Critical Strike"
  91. "Melee Hit Avoidance" "Ranged Hit Avoidance" "Spell Hit Avoidance"
  92. "Melee Critical Avoidance" "Spell Critical Avoidance" "Melee Haste Rating"
  93. "Ranged Haste Rating" "Spell Haste Rating" "Hit Avoidance Rating"
  94. "Hit Rating" "Critical Strike" "Hit Avoidance Rating"
  95. "Critical Avoidance Rating" "Resilience" "Haste"
  96. "Expertise" "Attack Power" "Ranged Attack Power"
  97. "No Visible Effect" "Healing Done By Magical Spells and Effects up to value" "Damage Done By Magical Spells and Effects up to value"
  98. "Mana Regeneration (Ticks every 5 seconds)" "Armor Penetration Rating" "Spell Power"
  99. "Health Regeneration (Ticks every 5 seconds)" "Spell Penetration" "Block Value of Shield"
  100. "Mastery" "Armor" "Fire Resist"
  101. "Frost Resist" "Shadow Resist" "Nature Resist"
  102. "Arcane Resist"]]
  103. (.. (. stat-names (+ n 1)) " (" n ")")))
  104. (fn stat-print [item]
  105. (var val "")
  106. (for [n 22 56]
  107. (if (< 0 (. item n))
  108. (set val (.. val " " (stat-name (- n 21)) ": " (. item n)))))
  109. val)
  110. ;; 5: main
  111. (global
  112. main
  113. (fn main [msg]
  114. (let [opts (icollect [v (string.gmatch msg "%w+")] v)
  115. [slot stat gear-index] opts
  116. slot (.. slot "Slot") ;; omit the need to type it out
  117. stat (+ 21 (tonumber stat)) ;; stats start after field 21, so agility (3) is 22+3, etc
  118. gear-index (tonumber (or gear-index "1"))
  119. inv-slot (GetInventorySlotInfo slot)
  120. i-link (GetInventoryItemLink "player" inv-slot)
  121. i-id (if i-link (parse-item-id i-link))
  122. p-level (UnitLevel "player")]
  123. (if (not i-link)
  124. ;; empty
  125. (let [best (.
  126. (find-good-item
  127. inv-slot
  128. (UnitLevel "player")
  129. stat
  130. 1
  131. (fn [a b] (and (< (. a stat) (. b stat))
  132. (< (. a 12) (. b 12)))))
  133. gear-index)]
  134. (if best
  135. (do
  136. (DEFAULT_CHAT_FRAME:AddMessage (string.format "\124Hitem:%d:0:0:0:0:0:0:0:0\124h[%s]\124h\124r" (. best 2) (. best 8)))
  137. (ui-print (.. "next best available: "
  138. (. best 8)
  139. " "
  140. (stat-print best)
  141. " at "
  142. (or (. best 20)) "N/A")))))
  143. ;; exists
  144. (let [i-name (GetItemInfo i-link)
  145. stats (find-item-by-name (un-quote i-name))]
  146. (if stats
  147. (let [i-class (. stats 4)
  148. i-subclass (. stats 6)
  149. i-invtype (. stats 10)
  150. i-level (. stats 12)
  151. i-stat (. stats stat)
  152. best (. (find-next-better-item i-class i-subclass i-invtype p-level i-level stat (max i-stat 1) (fn [a b] (< (. a stat) (. b stat)))) gear-index)]
  153. (if best
  154. (do
  155. (DEFAULT_CHAT_FRAME:AddMessage (string.format "\124Hitem:%d:0:0:0:0:0:0:0:0\124h[%s]\124h\124r" (. best 2) (. best 8)))
  156. (ui-print (.. "next best available: "
  157. (. best 8)
  158. " "
  159. (stat-print best)
  160. " at "
  161. (or (. best 20)) "N/A"))
  162. (ui-print (.. "currently equipped " i-name " " (or (. stats stat) "N/A"))))))
  163. (print (.. "Item " (un-quote i-name) " not found")))
  164. "ok")))))
  165. ;; unused
  166. (fn maxxed []
  167. (let [slots ["AmmoSlot"
  168. "BackSlot"
  169. "Bag0Slot"
  170. "Bag1Slot"
  171. "Bag2Slot"
  172. "Bag3Slot"
  173. "ChestSlot"
  174. "FeetSlot"
  175. "Finger0Slot"
  176. "Finger1Slot"
  177. "HandsSlot"
  178. "HeadSlot"
  179. "LegsSlot"
  180. "MainHandSlot"
  181. "NeckSlot"
  182. "RangedSlot"
  183. "SecondaryHandSlot"
  184. "ShirtSlot"
  185. "ShoulderSlot"
  186. "TabardSlot"
  187. "Trinket0Slot"
  188. "Trinket1Slot"
  189. "WaistSlot"
  190. "WristSlot"]]
  191. slots))