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.

226 lines
7.3KB

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