Advertisement
Guest User

Untitled

a guest
Jul 27th, 2016
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 38.75 KB | None | 0 0
  1. version = "6.0.6"
  2. --RandomMount
  3. --Original Author: Mike Hendricks(AttilaTheFun)
  4. --Continuing Author: t4t3rt0t
  5. --Description:
  6. -- This add-on makes it simple to summon a random mount it takes into account ridding level, cold weather flying,
  7. -- flying areas, Modifiers available, and summons an appropriate mount.
  8. -- It has a simple interface /mnt: /rmount: Will summon riding/flying mounts in the appropriate areas. mnt and rmount are interchangeable
  9. -- /mnt riding: Summons riding mounts in flying areas
  10. -- /mnt flying: Attempt to summon a flying mount
  11. -- /mnt help: Display help
  12. -- /mnt r or f (search Term): Summons a mount based on specified search term
  13. -- example: to summon a skeletal warhorse type: /mnt skeletal
  14. -- /mnt config: Prints the current configuration
  15. -- /mnt rfilter: Toggle mount filtering
  16. -- /mnt safefly: Toggle double click to dismount while flying
  17. -- /mnt rfilters: List current filters
  18. -- /mnt locfilter: Toggle filter to summon only specific mounts in specific locations
  19. -- /mnt addloc % (zone:mount name1, mount name2, ...): Add locations and mounts to location checking. Separate mounts with commas. Use * as a wildcard to specify all mounts.
  20. -- /mnt removeloc % (zone:mount name1, mount name2, ...): Removes locations and mounts from location checking. Separate mounts with commas.
  21. -- /mnt loctable: Print the current location filtering table.
  22. -- /mnt clearloc: Clears location filters
  23. -- /mnt remove %: Remove all mounts matching % if rfilter is enabled
  24. -- /mnt clear: Clears all filters
  25. -- /mnt clearrem: Clears the mount removal table
  26. -- /mnt whereami: Prints your zone and mini-map zone.
  27. -- /mnt title: Enable or disable random title change.
  28. -- /mnt icon: Enable or disable changing random mount macro icons to the last summoned mount.
  29. -- /mnt setweight # %: Sets a weight # (0 to 1000) for any mounts matching %. Omitting % will set the default weight for mounts without specified weights.
  30. -- /mnt PrintHelp("druid: Create a macro for druids that will cancel your form before trying to summon a mount.
  31. -- /mnt debug: Toggle debug printing for posting error messages
  32. -- /mnt No Flag: Summon a appropriate mount for the area
  33.  
  34. -- Addon namespace
  35. RMount = {}
  36.  
  37. -- Create frame for event handling
  38. local RMountFrame = CreateFrame("FRAME", "RMountFrame")
  39. RMountFrame:RegisterEvent("ADDON_LOADED")
  40. function RMount.OnEvent(this, event, ...)
  41. local arg1 = ...;
  42. if event == "ADDON_LOADED" and arg1 == "RandomMountContinued" then
  43. RMount:OnLoad()
  44. end
  45. end
  46. RMountFrame:SetScript("OnEvent", RMount.OnEvent)
  47.  
  48. -- Get the Frame that is housing the UIErrorsFrame
  49. local originalOnEvent = UIErrorsFrame:GetScript("OnEvent")
  50. -- Listen for SYSTEM Errors from the UIErrorsFrame
  51. UIErrorsFrame:SetScript("OnEvent", function(self, event, message, r, g, b, ...)
  52. -- Check the Error Message
  53. if message == SPELL_FAILED_NOT_HERE or message == SPELL_FAILED_ONLY_UNDERWATER then
  54. -- Set mountError to true
  55. mountError = true
  56. mountErrorMsg = message
  57. else
  58. -- Set mountError to false
  59. mountError = false
  60. mountErrorMsg = nil
  61. -- If error is not what we are looking for then return it to the original Frame
  62. return originalOnEvent(self, event, message, r, g, b, ...)
  63. end
  64. end)
  65.  
  66. -- Sea Mount Database
  67. -- GetCompanionInfo("MOUNT", i) doesn't provide a way to distinguish between (fast land/slow sea) and (slow land/fast sea)
  68. local seaMounts = {
  69. 30174, --Riding Turtle
  70. 64731, --Sea Turtle
  71. --the following should be detected as sea only, added anyways as fallback
  72. 98718, --Subdued Seahorse
  73. 75207 --Abyssal Seahorse
  74. }
  75.  
  76. -- Waterwalking Mount Database
  77. -- GetCompanionInfo("MOUNT", i) doesn't provide a way to distinguish waterwalking mounts
  78. local striderMounts = {
  79. 118089 --Azure Water Strider
  80. }
  81.  
  82.  
  83.  
  84.  
  85. --Old Saved Variables <1.06.13
  86. debug = false --display debug info if enabled
  87. notWanted = {} --Mounts that are not wanted to be summoned
  88. removeMount = false --Enable or disable notWanted mounts
  89. locationChk = true --enable or disable specific mounts in special locations
  90. locations = {} --locations to summon specific mounts(specialMounts)
  91. specialMounts = {} --special mounts to summon if in a specific location
  92. rndTitle = false --Randomly change the title when summoning a mount
  93. safeFly = false --Safe flying dismount if flying
  94. macroIcon = false --Update the macro icon with last summoned mount
  95. zones = {} --Contains the list of location filters
  96. mountError = false
  97. mountErrorMsg = nil
  98.  
  99.  
  100. --New Saved Variables >=1.06.13
  101. local defaultVars = {
  102. --only change version if DB format changes
  103. version = 1,
  104. useGVars = true,
  105. weights = {},
  106. defaultWeight = 100
  107. }
  108.  
  109. --upvars
  110. local mountCache = {} --cache data from GetCompanionInfo("MOUNT", i)
  111. local mountCount = {} --# of mounts, rebuild mountCache if it changes
  112. local lastTime = GetTime() --Safe flying last time that dismount was called
  113. local tailorSkill = 0
  114. local engineerSkill = 0
  115. local hasStrider = false
  116.  
  117. --bindings
  118. BINDING_HEADER_RANDOMMOUNT = "Random Mount"
  119. BINDING_NAME_RANDOMMOUNT_REG = "Auto Summon"
  120. BINDING_NAME_RANDOMMOUNT_RIDING = "Summon Riding"
  121. BINDING_NAME_RANDOMMOUNT_FLYING = "Summon Flying"
  122. BINDING_NAME_RANDOMMOUNT_SWIMMING = "Summon Swimming"
  123.  
  124. -- Run at Load
  125. function RMount:OnLoad()
  126. SlashCmdList["RandomMount"] = RMount.FindMount;
  127. SLASH_RandomMount1 = "/mnt";
  128. SLASH_RandomMount2 = "/rmount";
  129.  
  130. --Handle SavedVariables
  131. if not rMountCVars then
  132. rMountCVars = {}
  133. end
  134. RMount.CopyDefaultVars(defaultVars, rMountCVars)
  135. if not rMountGVars then
  136. rMountGVars = {}
  137. end
  138. RMount.CopyDefaultVars(defaultVars, rMountGVars)
  139. if rMountCVars.useGVars then
  140. rMountVars = rMountGVars
  141. else
  142. rMountVars = rMountCVars
  143. end
  144.  
  145. --[[ -- Save data for research purposes
  146. mountDB = {}
  147. for i=1, C_MountJournal.GetNumMounts() do
  148. local _, _, _, _, mountTypeID = C_MountJournal.GetMountInfoExtraByID(i)
  149. local mountName, spellID = C_MountJournal.GetMountInfoByID(i)
  150. if mountTypeID ~= 248 and mountTypeID ~= 230 and mountTypeID ~= 241 then
  151. tinsert(mountDB, {mountName, spellID, mountTypeID})
  152. end
  153. end
  154. ]]
  155. --[[
  156. local _, b, c, _, _, f = GetCompanionInfo("MOUNT", i)
  157. if not mountDB[f] then
  158. mountDB[f] = {}
  159. end
  160. if not mountDB[f][c] then
  161. mountDB[f][c] = {}
  162. end
  163. mountDB[f][c] = b
  164. if not (f == 7) and not (f == 12) and not (f == 15) and not (f == 23) and not (f == 29) and not (f == 31) then
  165. PrintHelp("Detected unknown mount mountTypeID flag: " .. f, "FFff0000")
  166. PrintHelp("Please help improve RandomMount by submitting this number on curse.com", "FFff0000")
  167. end
  168. end
  169. --]]
  170. end
  171.  
  172. function RMount.CopyDefaultVars(src, dst)
  173. if not src then return { } end
  174. if not dst then dst = { } end
  175. for k, v in pairs(src) do
  176. if type(v) == "table" then
  177. dst[k] = RMount.CopyDefaultVars(v, dst[k])
  178. elseif type(v) ~= type(dst[k]) then
  179. dst[k] = v
  180. end
  181. end
  182. return dst
  183. end
  184.  
  185. -- Build mountCache
  186. --[[
  187. mountTypeID 5th return of C_MountJournal.GetMountInfoExtraByID
  188. 284 (100011100) for 2 American Chopper bikes
  189. 269 (100001101) for 2 Water Striders (Azure and Crimson)
  190. 254 (11111110) for 1 Subdued Seahorse
  191. 248 (11111000) for 163 "typical" flying mounts, including those that change based on level (Tyreal's Charger, Celestial Steed)
  192. 247 (11110111) for 1 Red Flying Cloud (flying mount)
  193. 242 (11110010) for 2 Swift Spectral Gryphon/Rylak (the one we fly while dead? 10th return (hideOnChar) of GetMountInfo is true)
  194. 241 (11110001) for 4 Qiraji Battle Tanks (Blue, Green, Red and Yellow)
  195. 232 (11101000) for 1 Vashj'ir Seahorse
  196. 231 (11100111) for 2 Turtles (Riding and Sea)
  197. 230 (11100110) for 298 land mounts
  198. ]]--
  199. function BuildMountCache()
  200. mountCache = {air={}, land={}, sea={}, strider={}, all={}, find={}}
  201. mountCount = {air=0, land=0, sea=0, strider=0, all=0, find={}}
  202. mountTable = C_MountJournal.GetMountIDs()
  203. mountCount.all = C_MountJournal.GetNumMounts()
  204. for _,i in ipairs(mountTable) do
  205. --local creatureID, mountName, spellID, icon, _, mountFlags = GetCompanionInfo("MOUNT", i) -- 5.0 api
  206. local mountName, spellID, icon, active, isUsable, sourceType, isFavorite, isFactionSpecific, faction, hideOnChar, isCollected, mountID = C_MountJournal.GetMountInfoByID(i)
  207. local creatureDisplayID, descriptionText, sourceText, isSelfMount, mountTypeID = C_MountJournal.GetMountInfoExtraByID(i)
  208. if mountTypeID == 247 or mountTypeID == 248 then
  209. mountCache.air[i] = rMountVars.weights[spellID] or rMountVars.defaultWeight
  210. mountCount.air = mountCount.air + 1
  211. elseif mountTypeID == 231 or mountTypeID == 254 or IsSeaMount(spellID) then
  212. mountCache.sea[i] = rMountVars.weights[spellID] or rMountVars.defaultWeight
  213. mountCount.sea = mountCount.sea + 1
  214. end
  215. if mountTypeID == 230 or mountTypeID == 241 or mountTypeID == 269 then
  216. mountCache.land[i] = rMountVars.weights[spellID] or rMountVars.defaultWeight
  217. mountCount.land = mountCount.land + 1
  218. end
  219. if mountTypeID == 269 or IsStriderMount(spellID) then
  220. mountCache.strider[i] = rMountVars.weights[spellID] or rMountVars.defaultWeight
  221. mountCount.strider = mountCount.strider + 1
  222. hasStrider = true
  223. end
  224. mountCache.all[i] = {
  225. mountName,
  226. spellID,
  227. icon,
  228. mountTypeID,
  229. isCollected,
  230. faction
  231. }
  232. --[[
  233. --Check if mountTypeID flags don't match any known values
  234. if not (mountTypeID == 7) and not (mountTypeID == 12) and not (mountTypeID == 15) and
  235. not (mountTypeID == 23) and not (mountTypeID == 29) and not (mountTypeID == 31) then
  236. if debug then PrintHelp("Detected unknown mount mountTypeID flag: " .. mountTypeID, "FFff0000") end
  237.  
  238. --Determine land/air mountTypeID at least
  239. if bit.band(2,mountTypeID) == 2 then
  240. mountCache.air[i] = rMountVars.weights[spellID] or rMountVars.defaultWeight
  241. mountCount.air = mountCount.air + 1
  242. end
  243. if bit.band(16,mountTypeID) == 16 then
  244. mountCache.land[i] = rMountVars.weights[spellID] or rMountVars.defaultWeight
  245. mountCount.land = mountCount.land + 1
  246. end
  247. end
  248. ]]--
  249. end
  250. end
  251.  
  252. -- todo: combine BuildSearchCache with BuildMountCache
  253. -- todo: create function - mountTypes = DecodeMountTypes(mountTypeID)
  254. -- Create cache of mounts matching search pattern
  255. function BuildSearchCache(search)
  256. local spellID
  257. if not mountCache.find[search] then
  258. mountCache.find[search] = {air={}, land={}, sea={}, all={}}
  259. else
  260. -- bail if cache already exists
  261. return
  262. end
  263. if not mountCount.find[search] then
  264. mountCount.find[search] = {air=0, land=0, sea=0, all=0}
  265. end
  266.  
  267. mountTable = C_MountJournal.GetMountIDs()
  268. for _,i in ipairs(mountTable) do
  269. local searchComponents = splitString(",%s*", search)
  270. for _, searchComponent in ipairs(searchComponents) do
  271. if strfind(strlower(mountCache.all[i][1]), strlower(searchComponent)) then
  272. creatureSpellID = mountCache.all[i][2]
  273. mountTypeID = mountCache.all[i][4]
  274. mountCache.find[search].all[i] = rMountVars.weights[creatureSpellID] or rMountVars.defaultWeight
  275. mountCount.find[search].all = mountCount.find[search].all + 1
  276. if mountTypeID == 247 or mountTypeID == 248 then
  277. mountCache.find[search].air[i] = rMountVars.weights[creatureSpellID] or rMountVars.defaultWeight
  278. mountCount.find[search].air = mountCount.find[search].air + 1
  279. elseif mountTypeID == 231 or mountTypeID == 254 or IsSeaMount(spellID) then
  280. mountCache.find[search].sea[i] = rMountVars.weights[creatureSpellID] or rMountVars.defaultWeight
  281. mountCount.find[search].sea = mountCount.find[search].sea + 1
  282. end
  283. if mountTypeID == 230 or mountTypeID == 241 or mountTypeID == 269 then
  284. mountCache.find[search].land[i] = rMountVars.weights[creatureSpellID] or rMountVars.defaultWeight
  285. mountCount.find[search].land = mountCount.find[search].land + 1
  286. end
  287. end
  288. end
  289. end
  290. return
  291. end
  292.  
  293. -- Select a mount
  294. function GetRandomMount(type, ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  295. local count
  296. local lastMount
  297. local s = false
  298. local chance
  299. if search ~= '' then
  300. t = mountCache.find[search][type]
  301. else
  302. t = mountCache[type]
  303. end
  304. local total = GetMountWeightTotal(t)
  305.  
  306. for i=1, 10000 do
  307. count = random(0, total)
  308. for j, weight in pairs(t) do
  309. count = count - weight
  310. lastMount = j
  311. if count <= 0 then
  312. chance = weight * 100 / total
  313. break
  314. end
  315. end
  316. -- Test Mount
  317. s = TestMount(lastMount, ridingSK, zoneText, canFly, inLocation, zoneChk, chance)
  318. if s then
  319. break
  320. end
  321. end
  322. local casting = UnitCastingInfo("player")
  323. -- Summon Mount
  324. if s then
  325. C_MountJournal.SummonByID(lastMount)
  326. if not mountError and not casting then
  327. -- Set Icon of the Mount
  328. RMount.SetMacroIcon(lastMount)
  329. end
  330. end
  331. end
  332.  
  333. -- Count total of all weights
  334. function GetMountWeightTotal(mountTable)
  335. local total = 0
  336. for _, weight in pairs(mountTable) do
  337. total = total + weight
  338. end
  339. return total
  340. end
  341.  
  342. -- Check if mount can swim fast
  343. function IsSeaMount(spellID)
  344. for _, value in ipairs(seaMounts) do
  345. if value == spellID then
  346. return true
  347. end
  348. end
  349. return false
  350. end
  351.  
  352. -- Check if mount can waterwalk
  353. function IsStriderMount(spellID)
  354. for _, value in ipairs(striderMounts) do
  355. if value == spellID then
  356. return true
  357. end
  358. end
  359. return false
  360. end
  361.  
  362. -- Set weight of mounts matching nameSearch
  363. function SetMountWeights(weight, nameSearch)
  364. if weight then
  365. weight = min(floor(abs(weight)), 1000)
  366. end
  367. if nameSearch == '' then
  368. local oldweight = rMountVars.defaultWeight or 100
  369. rMountVars.defaultWeight = weight
  370. PrintHelp("Default weight changed from " .. oldweight .. " to " .. weight, "FF00ffff")
  371. else
  372. for i=1, mountCount.all do
  373. if strfind(strlower(mountCache.all[i][1]), strlower(nameSearch)) then
  374. local spellID = mountCache.all[i][2]
  375. local oldweight = rMountVars.weights[spellID] or rMountVars.defaultWeight
  376. rMountVars.weights[spellID] = weight
  377. if weight then
  378. PrintHelp(mountCache.all[i][1] .. " weight changed from " .. oldweight .. " to " .. weight, "FF00ffff")
  379. else
  380. PrintHelp(mountCache.all[i][1] .. " weight reset from " .. oldweight .. " to default " .. rMountVars.defaultWeight, "FF00ffff")
  381. end
  382. end
  383. end
  384. end
  385. --Rebuild cache with new weights
  386. BuildMountCache()
  387. end
  388.  
  389. -- Check if you can use a Sea mount in this zone
  390. function CanSwimHere()
  391. zone = GetCurrentMapAreaID()
  392. if mountCount.sea > 0 then
  393. for i, _ in pairs(mountCache.sea) do
  394. local spellID = mountCache.all[i][2]
  395. if spellID == 75207 and zone ~= 614 and zone ~= 615 and zone ~= 610 and mountCount.sea == 1 then
  396. return false
  397. end
  398. end
  399. return true
  400. end
  401. return false
  402. end
  403.  
  404. -- Check if you can fly in this zone
  405. function CanFlyHere()
  406. if mountCount.air == 0 then
  407. if debug then PrintHelp("No air mounts detected", "FFff0000") end
  408. return false
  409. end
  410. SetMapToCurrentZone()
  411. local zoneID = GetCurrentMapAreaID()
  412. -- local zoneNum = GetCurrentMapZone()
  413. local continent = GetCurrentMapContinent()
  414. local ridingSkill, classicLicense, coldLicense, pandaLicense, serpentLicense, dreanorLicense = GetRidingSkill()
  415.  
  416. -- Check for flyable area
  417. if not IsFlyableArea() then
  418. return false
  419. else
  420. -- ban flying in Throne of the Four Winds, The Deadmines
  421. if zoneID == 773 or zoneID == 756 then
  422. return false
  423. else
  424. -- Zone Check
  425. if classicLicense and (continent == 1 or continent == 2 or continent == 5) then
  426. return true
  427. elseif ridingSkill >= 225 and continent == 3 then
  428. return true
  429. elseif coldLicense and continent == 4 then
  430. return true
  431. elseif pandaLicense and continent == 6 then
  432. return true
  433. elseif dreanorLicense and continent == 7 then
  434. return true
  435. end
  436. end
  437.  
  438. if debug then PrintHelp("No flight license found for zoneID: ".. zoneID ..", continent: ".. continent, "FFff0000") end
  439. return false
  440. end
  441. end
  442.  
  443. -- Get your Riding Skill Level
  444. function GetRidingSkill()
  445. local ridingSkill = 0
  446. local classicLicense = false
  447. local coldLicense = false
  448. local pandaLicense = false
  449. local serpentLicense = false
  450. local dreanorLicense = false
  451.  
  452. if IsSpellKnown(90265) then
  453. ridingSkill = 375
  454. elseif IsSpellKnown(34091) then
  455. ridingSkill = 300
  456. elseif IsSpellKnown(34090) then
  457. ridingSkill = 225
  458. elseif IsSpellKnown(33391) then
  459. ridingSkill = 150
  460. elseif IsSpellKnown(33388) then
  461. ridingSkill = 75
  462. end
  463. if IsSpellKnown(90267) then
  464. classicLicense = true
  465. end
  466. if IsSpellKnown(54197) then
  467. coldLicense = true
  468. end
  469. if IsSpellKnown(115913) then
  470. pandaLicense = true
  471. end
  472. if IsSpellKnown(130487) then
  473. serpentLicense = true
  474. end
  475. if IsSpellKnown(191645) then
  476. dreanorLicense = true
  477. end
  478. return ridingSkill, classicLicense, coldLicense, pandaLicense, serpentLicense, dreanorLicense
  479. end
  480.  
  481. -- Get your Profession Skill Level
  482. function GetProfessionSkill()
  483. local prof1, prof2 = GetProfessions()
  484. prof1 = prof1 or 0
  485. prof2 = prof2 or 0
  486. local _, _, skill1, _, _, _, skillLine1 = GetProfessionInfo(prof1)
  487. local _, _, skill2, _, _, _, skillLine2 = GetProfessionInfo(prof2)
  488. skillLine1 = skillLine1 or 0
  489. skillLine2 = skillLine2 or 0
  490. if skillLine1 == 197 then
  491. tailorSkill = skill1 or 0
  492. elseif skillLine2 == 197 then
  493. tailorSkill = skill2 or 0
  494. end
  495. if skillLine1 == 202 then
  496. engineerSkill = skill1 or 0
  497. elseif skillLine2 == 202 then
  498. engineerSkill = skill2 or 0
  499. end
  500. end
  501.  
  502. -- Check Special Mounts
  503. function lfmChk(mountName)
  504. if locationChk then
  505. for j, k in ipairs(specialMounts) do
  506. if strfind(strlower(mountName), strlower(k)) then
  507. return true
  508. end
  509. end
  510. if #locations > 0 then
  511. PrintHelp("Detected location filtering usage. This feature may soon be removed.", "FFff0000")
  512. PrintHelp("If you would like this feature to remain then please comment on curse.com", "FFff0000")
  513. end
  514. end
  515. return false
  516. end
  517.  
  518. -- from http://lua-users.org/wiki/SplitJoin by PeterPrade
  519. function splitString(delimiter, text)
  520. local list = {}
  521. local pos = 1
  522. if strfind("", delimiter, 1) then -- this would result in endless loops
  523. error("delimiter matches empty string!")
  524. end
  525. while 1 do
  526. local first, last = strfind(text, delimiter, pos)
  527. if first then -- found?
  528. tinsert(list, strsub(text, pos, first-1))
  529. pos = last+1
  530. else
  531. tinsert(list, strsub(text, pos))
  532. break
  533. end
  534. end
  535. return list
  536. end
  537.  
  538. -- Add Mount to Locations List
  539. function AddLocF(info)
  540. if string.len(info) > 0 then
  541. local i = strfind(info, ":");
  542. local locVar = strsub(info, 0, i - 1)
  543. local mntVar = splitString(",", strsub(info, i + 1));
  544. if not zones[strlower(locVar)] then
  545. zones[strlower(locVar)] = {}
  546. end
  547. for i, v in ipairs(mntVar) do
  548. local found = false
  549. for n, item in ipairs(zones[strlower(locVar)]) do
  550. if v == item then
  551. PrintHelp(v .. " already added.", "FF00ff00")
  552. found = true
  553. break
  554. end
  555. end
  556. if not found then
  557. tinsert(zones[strlower(locVar)], v)
  558. end
  559. end
  560. PrintHelp("When in " .. strlower(locVar) .. " mounts with " .. table.concat(zones[strlower(locVar)], ",") .. " will be summoned.", "FF00ff00")
  561. end
  562. end
  563.  
  564. -- Print the Location List
  565. function printLocF()
  566. PrintHelp("Location Mount database", "FFff00ff")
  567. for i, v in pairs(zones) do
  568. PrintHelp(i .. ":", "FF00ff00")
  569. for j, w in ipairs(zones[i]) do
  570. PrintHelp(" " .. w, "FF00ff99")
  571. end
  572. end
  573. end
  574.  
  575. -- Remove a Filtered Location
  576. function removeLocF(info)
  577. if string.len(info) > 0 then
  578. local i = strfind(info, ":");
  579. --if : not found then remove zone table
  580. if not i then
  581. PrintHelp("Zone " .. info .. " is no longer filtered.", "FF00ff00")
  582. zones[info] = nil
  583. else
  584. local locVar = strsub(info, 0, i - 1)
  585. local mntVar = splitString(",", strsub(info, i + 1))
  586. for i, v in ipairs(mntVar) do
  587. local found = false
  588. for n, item in ipairs(zones[locVar]) do
  589. if v == item then
  590. PrintHelp(v .. " removed from " .. locVar .. ".", "FF00ff99")
  591. tremove(zones[locVar], n)
  592. found = true
  593. break
  594. end
  595. end
  596. if not found then
  597. PrintHelp(v .. " not found in " .. locVar .. ".", "FF00ff99")
  598. end
  599. end
  600. if #zones[locVar] == 0 then
  601. PrintHelp(locVar .. " removed because it has no mounts.", "FF00ff00")
  602. zones[locVar] = nil
  603. end
  604. end
  605. end
  606. -- if : found then remove zone table elements, not entire table, if table is empty place * to signify empty
  607. end
  608.  
  609. -- Change the Character Title
  610. function RMount.SetCharTitle()
  611. if rndTitle then
  612. local titles = {}
  613. for i=1,GetNumTitles() do
  614. if IsTitleKnown(i) then
  615. tinsert(titles, i)
  616. end
  617. end
  618. SetCurrentTitle(titles[random(#titles)])
  619. end
  620. end
  621.  
  622. -- Check to see if we are Swimming or in Vashj'ir
  623. function checkSwimming()
  624. local zone = GetCurrentMapAreaID()
  625. if IsSwimming() then
  626. return true
  627. elseif not IsSwimming() and (zone == 614 or zone == 615 or zone == 610) then
  628. return true
  629. else
  630. return false
  631. end
  632. end
  633.  
  634. -- Change the Macro Icon
  635. function RMount.SetMacroIcon(r)
  636. if macroIcon then
  637. local _, _, icon = C_MountJournal.GetMountInfoByID(r)
  638. -- loop to change the icons of macros that are calling /rmount
  639. local numglobal,numperchar = GetNumMacros()
  640. for j=1,numglobal do
  641. local mbody = GetMacroBody(j)
  642. if strfind(mbody,"/rmount") or strfind(mbody,"/mnt") then
  643. EditMacro(j,nil,strsub(icon,17),nil,nil)
  644. end
  645. end
  646. for j=37,numperchar+36 do
  647. local mbody = GetMacroBody(j)
  648. if strfind(mbody,"/rmount") or strfind(mbody,"/mnt") then
  649. EditMacro(j,nil,strsub(icon,17),nil,true)
  650. end
  651. end
  652. end
  653. end
  654.  
  655. -- Main Mount Call
  656. function RMount.FindMount(arg1)
  657. -- Check Profession Skills
  658. GetProfessionSkill()
  659. -- Check if # of mounts changed
  660. if (mountCount.all ~= C_MountJournal.GetNumMounts()) then
  661. BuildMountCache()
  662. end
  663. local s = 0
  664. local r
  665. local search = ""
  666. local zoneText = GetRealZoneText() -- Get Zone Text
  667. local canFly = CanFlyHere() -- Check if can fly
  668. local outdoors = IsOutdoors() -- Check if outdoors
  669. local ridingSK = GetRidingSkill() -- Set Riding Skill
  670. local inLocation = false --Used to check for location
  671. local zoneChk = true
  672. local removeMountPrev = removeMount
  673. local mountType = nil --air/land/sea mount
  674.  
  675. -- Check for macro modifiers
  676. argv, _ = SecureCmdOptionParse(arg1)
  677. -- Bail if no macro conditions matched
  678. if argv == nil then return end
  679.  
  680. -- Check argument after /mnt or /rmount
  681. if argv == "help" then
  682. PrintHelp("Random Mount " .. version .. " optional flags:", "FFFFFF00")
  683. PrintHelp("/mnt: /rmount: Will summon swimming/riding/flying mounts in the appropriate areas. mnt and rmount are interchangeable", "FFFFFF00")
  684. PrintHelp("riding: Attempt to summon a ground mount", "FFFFFF00")
  685. PrintHelp("flying: Attempt to summon a flying mount", "FFFFFF00")
  686. PrintHelp("swimming: Attempt to summon a swimming mount", "FFFFFF00")
  687. PrintHelp("help: Display help", "FFFFFF00")
  688. PrintHelp("[mod:Modifier Name]: Use any Modifier Blizzard Supports", "FFFFFF00")
  689. PrintHelp("r %: Summons a ground mount matching % search term \rexample: to summon a skeletal warhorse type: /mnt r skeletal", "FFFFFF00")
  690. PrintHelp("f %: Summons a flying mount matching % search term \rexample: to summon a proto-drake type: /mnt f proto", "FFFFFF00")
  691. PrintHelp("s %: Summons a swimming mount matching % search term \rexample: to summon a turtle type: /mnt s turtle", "FFFFFF00")
  692. PrintHelp("config: Prints the current configuration", "FFFFFF00")
  693. PrintHelp("safefly: Toggle double click to dismount while flying", "FFFFFF00")
  694. PrintHelp("rfilters: List current filters", "FFFFFF00")
  695. PrintHelp("locfilter: Toggle filter to summon only specific mounts in specific locations", "FFFFFF00")
  696. PrintHelp("addloc % (zone:mount name1, mount name2, ...): Add locations and mounts to location checking. Separate mounts with commas. Use * as a wildcard to specify all mounts.", "FFFFFF00")
  697. PrintHelp("removeloc % (zone:mount name1, mount name2, ...): Removes locations and mounts from location checking. Separate mounts with commas.", "FFFFFF00")
  698. PrintHelp("loctable: Print the current location filtering table.", "FFFFFF00")
  699. PrintHelp("clearloc: Clears location filters", "FFFFFF00")
  700. PrintHelp("remove %: Remove all mounts matching % if rfilter is enabled", "FFFFFF00")
  701. PrintHelp("clear: Clears all filters", "FFFFFF00")
  702. PrintHelp("clearrem: Clears the mount removal table", "FFFFFF00")
  703. PrintHelp("whereami: Prints your zone and mini-map zone, and map coordinates.", "FFFFFF00")
  704. PrintHelp("title: Enable or disable random title change.", "FFFFFF00")
  705. PrintHelp("icon: Enable or disable changing random mount macro icons to the last summoned mount.", "FFFFFF00")
  706. PrintHelp("setweight # %: Sets a weight # (0 to 1000) for any mounts matching %. \rOmitting % will set the default weight to # for mounts without specified weights. \rOmitting # will clear any weights set for any mounts matching %.", "FFFFFF00")
  707. PrintHelp("debug: Toggle debug printing for posting error messages", "FFFFFF00")
  708. return
  709. elseif argv == "config" then
  710. if debug then
  711. PrintHelp("Debug: Enabled", "FF00ff00")
  712. else
  713. PrintHelp("Debug: Disabled", "FFff0000")
  714. end
  715. if removeMount then
  716. PrintHelp("Mounts filtered: " .. table.concat(notWanted, ", "), "FF00ff00")
  717. else
  718. PrintHelp("Mount Removal Disabled.", "FFff0000")
  719. end
  720. if safeFly then
  721. PrintHelp("Safe flying enabled. Double click to dismount while flying", "FF00ff00")
  722. else
  723. PrintHelp("Safe flying disabled.", "FFff0000")
  724. end
  725. if rndTitle then
  726. PrintHelp("Random title enabled.", "FF00ff00")
  727. else
  728. PrintHelp("Random title disabled.", "FFff0000")
  729. end
  730. if macroIcon then
  731. PrintHelp("Icon changing enabled.", "FF00ff00")
  732. else
  733. PrintHelp("Icon changing disabled.", "FFff0000")
  734. end
  735. return
  736. elseif argv == "whereami" then
  737. local posX, posY = GetPlayerMapPosition("player")
  738. PrintHelp("You are in " .. zoneText .. ", " .. GetMinimapZoneText() .. ", " .. posX .. ", " .. posY, "FF00ff00")
  739. return
  740. elseif argv == "debug" then
  741. if debug == false then
  742. debug = true
  743. PrintHelp("Debug information enabled.", "FF00ff00")
  744. elseif debug == true then
  745. debug = false
  746. PrintHelp("Debug information disabled.", "FFff0000")
  747. end
  748. return
  749. elseif argv == "locfilter" then
  750. if locationChk == false then
  751. locationChk = true
  752. PrintHelp("Location mount filtering enabled.", "FF00ff00")
  753. elseif locationChk == true then
  754. locationChk = false
  755. PrintHelp("Location mount filtering disabled.", "FFff0000")
  756. end
  757. return
  758. elseif argv == "rfilter" then
  759. if removeMount == false then
  760. removeMount = true
  761. removeMountPrev = removeMount
  762. PrintHelp("Mount removal enabled.", "FF00ff00")
  763. elseif removeMount == true then
  764. removeMount = false
  765. removeMountPrev = removeMount
  766. PrintHelp("Mount removal disabled.", "FFff0000")
  767. end
  768. return
  769. elseif argv == "safefly" then
  770. if safeFly == false then
  771. safeFly = true
  772. PrintHelp("Safe flying enabled. Double click to dismount while flying", "FF00ff00")
  773. elseif safeFly == true then
  774. safeFly = false
  775. PrintHelp("Safe flying disabled.", "FFff0000")
  776. end
  777. return
  778. elseif argv == "rfilters" then
  779. if removeMount then
  780. PrintHelp("Mounts filtered: " .. table.concat(notWanted, ", "), "FF00ffff")
  781. else
  782. PrintHelp("Mount removal disabled.", "FFff0000")
  783. end
  784. return
  785. elseif argv == "title" then
  786. if rndTitle == false then
  787. rndTitle = true
  788. PrintHelp("Random title enabled.", "FF00ff00")
  789. elseif rndTitle == true then
  790. rndTitle = false
  791. PrintHelp("Random title disabled.", "FFff0000")
  792. end
  793. return
  794. elseif argv == "icon" then
  795. if macroIcon == false then
  796. macroIcon = true
  797. PrintHelp("Icon changing enabled.", "FF00ff00")
  798. elseif macroIcon == true then
  799. macroIcon = false
  800. PrintHelp("Icon changing disabled.", "FFff0000")
  801. end
  802. return
  803. elseif argv == "clear" then
  804. notWanted = {}
  805. zones = {}
  806. PrintHelp("All tables cleared.", "FF00ffff")
  807. return
  808. elseif argv == "clearrem" then
  809. notWanted = {}
  810. PrintHelp("Remove mount table cleared.", "FF00ffff")
  811. return
  812. elseif argv == "clearloc" then
  813. zones = {}
  814. PrintHelp("Special location table cleared.", "FF00ffff")
  815. return
  816. elseif argv == "loctable" then
  817. printLocF()
  818. return
  819. elseif argv:find("removeloc") then
  820. PrintHelp(strsub(argv, 11), "FF00ff99")
  821. if string.len(strsub(argv, 11)) > 0 then
  822. removeLocF(strsub(argv, 11))
  823. end
  824. return
  825. elseif argv == "riding" then
  826. mountType = "land"
  827. elseif argv == "flying" then
  828. mountType = "air"
  829. elseif argv == "swimming" then
  830. mountType = "sea"
  831. elseif argv:find("addloc") then
  832. if string.len(strsub(argv, 8)) > 0 then
  833. AddLocF(strsub(argv, 8))
  834. end
  835. return
  836. elseif argv:find("remove") then
  837. local found = false
  838. if strlen(strsub(argv, 8)) > 0 then
  839. for n, notW in ipairs(notWanted) do
  840. if strsub(argv, 8) == notW then
  841. PrintHelp(strsub(argv, 8) .. " already added.", "FF00ffff")
  842. found = true
  843. break
  844. end
  845. end
  846. --PrintHelp(table.concat(notWanted, ", "), "FF00ffff")
  847. if not found then
  848. PrintHelp("Mounts matching " .. strsub(argv, 8) .. " will no longer be summoned.", "FF00ff00")
  849. tinsert(notWanted, strsub(argv, 8))
  850. end
  851. end
  852. return
  853. elseif argv:find("setweight") then
  854. argv = strsub(argv, 11) or ""
  855. if strlen(argv) > 0 then
  856. local weight = string.match(argv, "%d+")
  857. local nameSearch = string.match(argv, "%a[%a%s]*%a$") or ""
  858. SetMountWeights(weight, nameSearch)
  859. end
  860. return
  861. -- elseif argv == "rnd" then
  862. -- r = random(C_MountJournal.GetNumMounts)
  863. -- PrintHelp(r, "FF00ffff")
  864. elseif strfind(argv, "r%s", 1) then
  865. mountType = "land"
  866. search = strlower(strsub(argv, 3))
  867. elseif strfind(argv, "f%s", 1) then
  868. mountType = "air"
  869. search = strlower(strsub(argv, 3))
  870. elseif strfind(argv, "s%s", 1) then
  871. mountType = "sea"
  872. search = strlower(strsub(argv, 3))
  873. else
  874. search = strlower(strsub(argv, 1))
  875. end
  876. -- Check if we are Mounted
  877. if IsMounted() then
  878. if safeFly and IsFlying() then
  879. local curTime = GetTime()
  880. if curTime < (lastTime + 0.5) then
  881. Dismount()
  882. return
  883. else
  884. lastTime = curTime
  885. return
  886. end
  887. else
  888. Dismount()
  889. return
  890. end
  891. elseif CanExitVehicle() then
  892. VehicleExit()
  893. return
  894. end
  895. -- Run Random Title
  896. RMount.SetCharTitle()
  897. -- Bail if no riding skill, no mounts, or if all-terrain mounts(land/sea/air) are not currently usable
  898. if ridingSK < 75 or mountCount.all == 0 or not IsUsableSpell(121838) then return end
  899. -- Process Search Mount
  900. if search ~= '' then
  901. if mountType == nil then
  902. mountType = "all"
  903. end
  904. BuildSearchCache(search, mountType)
  905. if mountCount.find[search][mountType] > 0 then
  906. GetRandomMount(mountType, ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  907. else
  908. PrintHelp("No matching mount found.", "FF00ffff")
  909. end
  910. return
  911. end
  912.  
  913. -- If type specified then use it
  914. if mountType then
  915. GetRandomMount(mountType, ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  916. -- Check if swimming and not at the surface/can't fly
  917. elseif checkSwimming() and not IsUsableSpell(130092) then
  918. -- Check if have usable sea mounts
  919. if CanSwimHere() then
  920. GetRandomMount("sea", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  921. else
  922. -- We might be under the surface with no sea mounts, or we can't fly
  923. -- Try to get an air mount first but few air mounts also work underwater
  924. if canFly then
  925. GetRandomMount("air", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  926. -- Check if we have a waterwalking mount
  927. elseif hasStrider then
  928. GetRandomMount("strider", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  929. end
  930. end
  931. -- Some indoor places in Vashj'ir like Nespirah can only use land mounts even though swimming checks all pass
  932. -- So try to get a land mount in case we're indoors in Vashj'ir or at the surface and can't fly
  933. -- It might summon the land mount even if another is already being summoned
  934. GetRandomMount("land", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  935. -- Check if we can fly
  936. elseif canFly then
  937. GetRandomMount("air", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  938. else
  939. GetRandomMount("land", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  940. end
  941.  
  942. --[[
  943. -- Check if you Can Fly, IsUsableSpell used for swimming on surface check
  944. if canFly and IsUsableSpell(88744) then
  945. -- Repeat picking a Mount until one is found that is appropriate
  946. GetRandomMount("air", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  947. -- Check if Summon Failed
  948. if mountError then
  949. canFly = false
  950. -- Check if you are Swimming
  951. if checkSwimming() then
  952. -- Get Sea Mount
  953. GetRandomMount("sea", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  954. end
  955. -- Reset mountError
  956. mountError = false
  957. -- Repeat picking a Mount until one is found that is appropriate
  958. GetRandomMount("air", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  959. -- Check if Summon Failed
  960. if mountError then
  961. PrintHelp("Cannot Summon Mount", "FFff0000")
  962. end
  963. end
  964. else
  965. -- Check if you are Swimming
  966. if checkSwimming() then
  967. -- Get Sea Mount
  968. GetRandomMount("sea", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  969. end
  970. mountError = false
  971. if mountCount.land ~= 0 then
  972. -- Repeat picking a Mount until one is found that is appropriate
  973. GetRandomMount("land", ridingSK, zoneText, canFly, search, inLocation, zoneChk)
  974. -- Check if Summon Failed
  975. if mountError then
  976. PrintHelp("Cannot Summon Mount", "FFff0000")
  977. end
  978. end
  979. end
  980. ]]--
  981.  
  982. return
  983. end
  984.  
  985. -- Test the Mount
  986. function TestMount(r, ridingSK, zoneText, canFly, inLocation, zoneChk, chance)
  987. local mountName = mountCache.all[r][1]
  988. local spellID = mountCache.all[r][2]
  989. local mountTypeID = mountCache.all[r][4]
  990. local isCollected = mountCache.all[r][5]
  991. local faction = mountCache.all[r][6]
  992. local realZone = GetCurrentMapAreaID()
  993.  
  994. -- Check if we have it
  995. if not isCollected then
  996. if debug then PrintHelp("Mount is not collected - Name: " .. mountName .. ", ID: " .. spellID, "FFff0000") end
  997. return false
  998. end
  999. -- Check if unusable (does not ensure it's usable)
  1000. local usable = IsUsableSpell(spellID)
  1001. if not usable then
  1002. if debug then PrintHelp("IsUsableSpell() returned false - Name: " .. mountName .. ", ID: " .. spellID, "FFff0000") end
  1003. return false
  1004. end
  1005. -- Check if our faction can use it
  1006. local factionGroup = UnitFactionGroup("player")
  1007. if (factionGroup == "Horde" and faction == 1) or (factionGroup == "Alliance" and faction == 0) then
  1008. if debug then PrintHelp("Mount is other faction - Name: " .. mountName .. ", ID: " .. spellID, "FFff0000") end
  1009. return false
  1010. end
  1011. --Remove Mount processing
  1012. if removeMount then
  1013. for n, notW in ipairs(notWanted) do
  1014. if strfind(strlower(mountName), strlower(notW)) or spellID == tonumber(notW) then
  1015. return false
  1016. end
  1017. end
  1018. end
  1019. --Abyssal Seahorse
  1020. if spellID == 75207 and realZone ~= 614 and realZone ~= 615 and realZone ~= 610 then
  1021. return false
  1022. end
  1023. --profession mounts
  1024. if (spellID == 44153 and engineerSkill < 300) or
  1025. (spellID == 44151 and engineerSkill < 375) or
  1026. (spellID == 61451 and tailorSkill < 300) or
  1027. (spellID == 75596 and tailorSkill < 425) or
  1028. (spellID == 61309 and tailorSkill < 425) then
  1029. if debug then PrintHelp("Profession skill too low - Name: " .. mountName .. ", ID: " .. spellID, "FFff0000") end
  1030. return false
  1031. end
  1032. --Zone Checking
  1033. if locationChk and zoneChk then
  1034. miniMapZone = GetMinimapZoneText()
  1035. local found = false
  1036. if zones[strlower(miniMapZone)] then
  1037. zoneChk = false
  1038. for i, type in ipairs(zones[strlower(miniMapZone)]) do
  1039. if strfind(strlower(mountName), strlower(type)) or type == "*" then
  1040. zoneChk = true
  1041. found = true
  1042. if debug then PrintHelp(type .. " : " .. mountName .. " is found", "FFffff00") end
  1043. break
  1044. end
  1045. end
  1046. end
  1047. -- Check your Zone
  1048. if zones[strlower(zoneText)] then
  1049. if not found then
  1050. zoneChk = false
  1051. for i, type in ipairs(zones[strlower(zoneText)]) do
  1052. if strfind(strlower(mountName), strlower(type)) or type == "*" then
  1053. zoneChk = true
  1054. if debug then PrintHelp(type .. " : " .. mountName .. " is found", "FFffff00") end
  1055. break
  1056. end
  1057. end
  1058. end
  1059. end
  1060. if not zoneChk then
  1061. return false
  1062. end
  1063. end
  1064. --flying mounts
  1065. if canFly then
  1066. if inLocation then
  1067. if lfmChk(mountName) then
  1068. if debug then PrintSummon("FF00ffff", mountName, r, ridingSK, mountTypeID, zoneText, canFly, spellID, chance, 11) end
  1069. return true
  1070. end
  1071. else
  1072. if debug then PrintSummon("FF00ffff", mountName, r, ridingSK, mountTypeID, zoneText, canFly, spellID, chance, 10) end
  1073. return true
  1074. end
  1075. --Regular Mounts
  1076. else
  1077. if inLocation then
  1078. if lfmChk(mountName) then
  1079. if debug then PrintSummon("FF00ffff", mountName, r, ridingSK, mountTypeID, zoneText, canFly, spellID, chance, 51) end
  1080. return true
  1081. end
  1082. else
  1083. if debug then PrintSummon("FF00ffff", mountName, r, ridingSK, mountTypeID, zoneText, canFly, spellID, chance, 50) end
  1084. return true
  1085. end
  1086. end
  1087. end
  1088.  
  1089. -- Print Help
  1090. function PrintHelp(cmd, color)
  1091. print(format('|c%s%s|r', color, cmd))
  1092. end
  1093.  
  1094. -- Print in Summon Color
  1095. function PrintSummon(color, mountName, r, ridingSK, mountTypeID, zoneText, canFly, spellID, chance, errorNum)
  1096. canFly = tostring(canFly)
  1097. print(format("|c%s%s - Mnt#:%s - Skill: %s - type:%s - %s - %s - flyZone:%s - cID:%s - chance:%.2f%% - cond:%s|r", color, mountName, r, ridingSK, mountTypeID, zoneText, GetMinimapZoneText(), canFly, spellID, chance, errorNum))
  1098. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement