Advertisement
Guest User

Untitled

a guest
Jun 1st, 2017
571
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.48 KB | None | 0 0
  1. -- ***************************************************
  2. -- ** DBM Range Check Frame **
  3. -- ** http://www.deadlybossmods.com **
  4. -- ***************************************************
  5. --
  6. -- This addon is written and copyrighted by:
  7. -- * Paul Emmerich (Tandanu @ EU-Aegwynn) (DBM-Core)
  8. -- * Martin Verges (Nitram @ EU-Azshara) (DBM-GUI)
  9. --
  10. -- The localizations are written by:
  11. -- * enGB/enUS: Tandanu http://www.deadlybossmods.com
  12. -- * deDE: Tandanu http://www.deadlybossmods.com
  13. -- * zhCN: Diablohu http://wow.gamespot.com.cn
  14. -- * ruRU: BootWin bootwin@gmail.com
  15. -- * ruRU: Vampik admin@vampik.ru
  16. -- * zhTW: Hman herman_c1@hotmail.com
  17. -- * zhTW: Azael/kc10577 paul.poon.kw@gmail.com
  18. -- * koKR: BlueNyx/nBlueWiz bluenyx@gmail.com / everfinale@gmail.com
  19. -- * esES: Snamor/1nn7erpLaY romanscat@hotmail.com
  20. --
  21. -- Special thanks to:
  22. -- * Arta
  23. -- * Omegal @ US-Whisperwind (continuing mod support for 3.2+)
  24. -- * Tennberg (a lot of fixes in the enGB/enUS localization)
  25. --
  26. --
  27. -- The code of this addon is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License. (see license.txt)
  28. -- All included textures and sounds are copyrighted by their respective owners.
  29. --
  30. --
  31. -- You are free:
  32. -- * to Share ?to copy, distribute, display, and perform the work
  33. -- * to Remix ?to make derivative works
  34. -- Under the following conditions:
  35. -- * Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).
  36. -- * Noncommercial. You may not use this work for commercial purposes.
  37. -- * Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same or similar license to this one.
  38. --
  39. --
  40. -- This file makes use of the following free (Creative Commons Sampling Plus 1.0) sounds:
  41. -- * alarmclockbeeps.ogg by tedthetrumpet (http://www.freesound.org/usersViewSingle.php?id=177)
  42. -- * blip_8.ogg by Corsica_S (http://www.freesound.org/usersViewSingle.php?id=7037)
  43. -- The full of text of the license can be found in the file "Sounds\Creative Commons Sampling Plus 1.0.txt".
  44.  
  45. ---------------
  46. -- Globals --
  47. ---------------
  48. DBM.RangeCheck = {}
  49.  
  50.  
  51. --------------
  52. -- Locals --
  53. --------------
  54. local rangeCheck = DBM.RangeCheck
  55. local checkFuncs = {}
  56. local frame
  57. local createFrame
  58. local radarFrame
  59. local createRadarFrame
  60. local onUpdate
  61. local onUpdateRadar
  62. local dropdownFrame
  63. local initializeDropdown
  64. local initRangeCheck -- initializes the range check for a specific range (if necessary), returns false if the initialization failed (because of a map range check in an unknown zone)
  65. local dots = {}
  66. local charms = {}
  67. local BREADTH_PLAYER_TOLERANCE = 3
  68.  
  69. -- for Phanx' Class Colors
  70. local RAID_CLASS_COLORS = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS
  71. local BLIP_TEX_COORDS = {
  72. ["WARRIOR"] = { 0, 0.125, 0, 0.25 },
  73. ["PALADIN"] = { 0.125, 0.25, 0, 0.25 },
  74. ["HUNTER"] = { 0.25, 0.375, 0, 0.25 },
  75. ["ROGUE"] = { 0.375, 0.5, 0, 0.25 },
  76. ["PRIEST"] = { 0.5, 0.625, 0, 0.25 },
  77. ["DEATHKNIGHT"] = { 0.625, 0.75, 0, 0.25 },
  78. ["SHAMAN"] = { 0.75, 0.875, 0, 0.25 },
  79. ["MAGE"] = { 0.875, 1, 0, 0.25 },
  80. ["WARLOCK"] = { 0, 0.125, 0.25, 0.5 },
  81. ["DRUID"] = { 0.25, 0.375, 0.25, 0.5 }
  82. }
  83. local CHARM_TEX_COORDS = {
  84. [1] = { 0, 0.25, 0, 0.25 },
  85. [2] = { 0.25, 0.5, 0, 0.25 },
  86. [3] = { 0.5, 0.75, 0, 0.25 },
  87. [4] = { 0.75, 1, 0, 0.25 },
  88. [5] = { 0, 0.25, 0.25, 0.5 },
  89. [6] = { 0.25, 0.5, 0.25, 0.5 },
  90. [7] = { 0.5, 0.75, 0.25, 0.5 },
  91. [8] = { 0.75, 1, 0.25, 0.5 }
  92. }
  93. ---------------------
  94. -- Dropdown Menu --
  95. ---------------------
  96.  
  97. -- todo: this dropdown menu is somewhat ugly and unflexible....
  98. do
  99. local function setRange(self, range)
  100. rangeCheck:Show(range)
  101. end
  102.  
  103. local sound0 = "none"
  104. local sound1 = "Interface\\AddOns\\DBM-Core\\Sounds\\blip_8.ogg"
  105. local sound2 = "Interface\\AddOns\\DBM-Core\\Sounds\\alarmclockbeeps.ogg"
  106. local function setSound(self, option, sound)
  107. DBM.Options[option] = sound
  108. if sound ~= "none" then
  109. if DBM.Options.UseMasterVolume then
  110. PlaySoundFile(sound, "Master")
  111. else
  112. PlaySoundFile(sound)
  113. end
  114. end
  115. end
  116.  
  117. local function setFrames(self, option)
  118. DBM.Options.RangeFrameFrames = option
  119. radarFrame:Hide()
  120. frame:Hide()
  121. rangeCheck:Show(frame.range, frame.filter)
  122. end
  123.  
  124. -- local function setSpeed(self, option)
  125. -- DBM.Options.RangeFrameUpdates = option
  126. -- end
  127.  
  128. local function toggleLocked()
  129. DBM.Options.RangeFrameLocked = not DBM.Options.RangeFrameLocked
  130. end
  131.  
  132. local function toggleRadar()
  133. DBM.Options.RangeFrameRadar = not DBM.Options.RangeFrameRadar
  134. if DBM.Options.RangeFrameRadar then
  135. radarFrame = radarFrame or createRadarFrame()
  136. radarFrame:Show()
  137. else
  138. radarFrame:Hide()
  139. end
  140. end
  141.  
  142. function initializeDropdown(dropdownFrame, level, menu)
  143. local info
  144. if level == 1 then
  145. info = UIDropDownMenu_CreateInfo()
  146. info.text = DBM_CORE_RANGECHECK_SETRANGE
  147. info.notCheckable = true
  148. info.hasArrow = true
  149. info.menuList = "range"
  150. UIDropDownMenu_AddButton(info, 1)
  151.  
  152. info = UIDropDownMenu_CreateInfo()
  153. info.text = DBM_CORE_RANGECHECK_SOUNDS
  154. info.notCheckable = true
  155. info.hasArrow = true
  156. info.menuList = "sounds"
  157. UIDropDownMenu_AddButton(info, 1)
  158.  
  159. info = UIDropDownMenu_CreateInfo()
  160. info.text = DBM_CORE_RANGECHECK_OPTION_FRAMES
  161. info.notCheckable = true
  162. info.hasArrow = true
  163. info.menuList = "frames"
  164. UIDropDownMenu_AddButton(info, 1)
  165.  
  166. --[[ info = UIDropDownMenu_CreateInfo()
  167. info.text = DBM_CORE_RANGECHECK_OPTION_SPEED
  168. info.notCheckable = true
  169. info.hasArrow = true
  170. info.menuList = "speed"
  171. UIDropDownMenu_AddButton(info, 1)]]
  172.  
  173. info = UIDropDownMenu_CreateInfo()
  174. info.text = DBM_CORE_RANGECHECK_LOCK
  175. if DBM.Options.RangeFrameLocked then
  176. info.checked = true
  177. end
  178. info.func = toggleLocked
  179. UIDropDownMenu_AddButton(info, 1)
  180.  
  181. info = UIDropDownMenu_CreateInfo()
  182. info.text = DBM_CORE_RANGECHECK_HIDE
  183. info.notCheckable = true
  184. info.func = rangeCheck.Hide
  185. info.arg1 = rangeCheck
  186. UIDropDownMenu_AddButton(info, 1)
  187.  
  188. elseif level == 2 then
  189. if menu == "range" then
  190. if initRangeCheck() then
  191. info = UIDropDownMenu_CreateInfo()
  192. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(3)
  193. info.func = setRange
  194. info.arg1 = 3
  195. info.checked = (frame.range == 3)
  196. UIDropDownMenu_AddButton(info, 2)
  197. end
  198.  
  199. if initRangeCheck() then
  200. info = UIDropDownMenu_CreateInfo()
  201. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(4)
  202. info.func = setRange
  203. info.arg1 = 4
  204. info.checked = (frame.range == 4)
  205. UIDropDownMenu_AddButton(info, 2)
  206. end
  207.  
  208. if initRangeCheck() then
  209. info = UIDropDownMenu_CreateInfo()
  210. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(5)
  211. info.func = setRange
  212. info.arg1 = 5
  213. info.checked = (frame.range == 5)
  214. UIDropDownMenu_AddButton(info, 2)
  215. end
  216.  
  217. if initRangeCheck() then
  218. info = UIDropDownMenu_CreateInfo()
  219. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(6)
  220. info.func = setRange
  221. info.arg1 = 6
  222. info.checked = (frame.range == 6)
  223. UIDropDownMenu_AddButton(info, 2)
  224. end
  225.  
  226. if initRangeCheck() then
  227. info = UIDropDownMenu_CreateInfo()
  228. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(8)
  229. info.func = setRange
  230. info.arg1 = 8
  231. info.checked = (frame.range == 8)
  232. UIDropDownMenu_AddButton(info, 2)
  233. end
  234.  
  235. info = UIDropDownMenu_CreateInfo()
  236. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(10)
  237. info.func = setRange
  238. info.arg1 = 10
  239. info.checked = (frame.range == 10)
  240. UIDropDownMenu_AddButton(info, 2)
  241.  
  242. info = UIDropDownMenu_CreateInfo()
  243. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(11)
  244. info.func = setRange
  245. info.arg1 = 11
  246. info.checked = (frame.range == 11)
  247. UIDropDownMenu_AddButton(info, 2)
  248.  
  249. if initRangeCheck() then
  250. info = UIDropDownMenu_CreateInfo()
  251. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(12)
  252. info.func = setRange
  253. info.arg1 = 12
  254. info.checked = (frame.range == 12)
  255. UIDropDownMenu_AddButton(info, 2)
  256. end
  257.  
  258. info = UIDropDownMenu_CreateInfo()
  259. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(15)
  260. info.func = setRange
  261. info.arg1 = 15
  262. info.checked = (frame.range == 15)
  263. UIDropDownMenu_AddButton(info, 2)
  264.  
  265. if initRangeCheck() then
  266. info = UIDropDownMenu_CreateInfo()
  267. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(20)
  268. info.func = setRange
  269. info.arg1 = 20
  270. info.checked = (frame.range == 20)
  271. UIDropDownMenu_AddButton(info, 2)
  272. end
  273.  
  274. info = UIDropDownMenu_CreateInfo()
  275. info.text = DBM_CORE_RANGECHECK_SETRANGE_TO:format(28)
  276. info.func = setRange
  277. info.arg1 = 28
  278. info.checked = (frame.range == 28)
  279. UIDropDownMenu_AddButton(info, 2)
  280. elseif menu == "sounds" then
  281. info = UIDropDownMenu_CreateInfo()
  282. info.text = DBM_CORE_RANGECHECK_SOUND_OPTION_1
  283. info.notCheckable = true
  284. info.hasArrow = true
  285. info.menuList = "RangeFrameSound1"
  286. UIDropDownMenu_AddButton(info, 2)
  287.  
  288. info = UIDropDownMenu_CreateInfo()
  289. info.text = DBM_CORE_RANGECHECK_SOUND_OPTION_2
  290. info.notCheckable = true
  291. info.hasArrow = true
  292. info.menuList = "RangeFrameSound2"
  293. UIDropDownMenu_AddButton(info, 2)
  294. elseif menu == "frames" then
  295. info = UIDropDownMenu_CreateInfo()
  296. info.text = DBM_CORE_RANGECHECK_OPTION_TEXT
  297. info.func = setFrames
  298. info.arg1 = "text"
  299. info.checked = (DBM.Options.RangeFrameFrames == "text")
  300. UIDropDownMenu_AddButton(info, 2)
  301.  
  302. info = UIDropDownMenu_CreateInfo()
  303. info.text = DBM_CORE_RANGECHECK_OPTION_RADAR
  304. info.func = setFrames
  305. info.arg1 = "radar"
  306. info.checked = (DBM.Options.RangeFrameFrames == "radar")
  307. UIDropDownMenu_AddButton(info, 2)
  308.  
  309. info = UIDropDownMenu_CreateInfo()
  310. info.text = DBM_CORE_RANGECHECK_OPTION_BOTH
  311. info.func = setFrames
  312. info.arg1 = "both"
  313. info.checked = (DBM.Options.RangeFrameFrames == "both")
  314. UIDropDownMenu_AddButton(info, 2)
  315. end
  316. elseif level == 3 then
  317. local option = menu
  318. info = UIDropDownMenu_CreateInfo()
  319. info.text = DBM_CORE_RANGECHECK_SOUND_0
  320. info.func = setSound
  321. info.arg1 = option
  322. info.arg2 = sound0
  323. info.checked = (DBM.Options[option] == sound0)
  324. UIDropDownMenu_AddButton(info, 3)
  325.  
  326. info = UIDropDownMenu_CreateInfo()
  327. info.text = DBM_CORE_RANGECHECK_SOUND_1
  328. info.func = setSound
  329. info.arg1 = option
  330. info.arg2 = sound1
  331. info.checked = (DBM.Options[option] == sound1)
  332. UIDropDownMenu_AddButton(info, 3)
  333.  
  334. info = UIDropDownMenu_CreateInfo()
  335. info.text = DBM_CORE_RANGECHECK_SOUND_2
  336. info.func = setSound
  337. info.arg1 = option
  338. info.arg2 = sound2
  339. info.checked = (DBM.Options[option] == sound2)
  340. UIDropDownMenu_AddButton(info, 3)
  341. end
  342. end
  343. end
  344.  
  345. -----------------
  346. -- Play Sounds --
  347. -----------------
  348. local function updateSound(numPlayers) -- called every 5 seconds
  349. if not UnitAffectingCombat("player") then
  350. return
  351. end
  352. if numPlayers == 1 then
  353. if DBM.Options.RangeFrameSound1 ~= "none" then
  354. if DBM.Options.UseMasterVolume then
  355. PlaySoundFile(DBM.Options.RangeFrameSound1, "Master")
  356. else
  357. PlaySoundFile(DBM.Options.RangeFrameSound1)
  358. end
  359. end
  360. elseif numPlayers > 1 then
  361. if DBM.Options.RangeFrameSound2 ~= "none" then
  362. if DBM.Options.UseMasterVolume then
  363. PlaySoundFile(DBM.Options.RangeFrameSound2, "Master")
  364. else
  365. PlaySoundFile(DBM.Options.RangeFrameSound2)
  366. end
  367. end
  368. end
  369. end
  370.  
  371. ------------------------
  372. -- Create the frame --
  373. ------------------------
  374. function createFrame()
  375. local elapsed = 0
  376. --[[ local updateRate
  377. if DBM.Options.RangeFrameUpdates == "Slow" then
  378. updateRate = 0.5
  379. elseif DBM.Options.RangeFrameUpdates == "Average" then
  380. updateRate = 0.25
  381. elseif DBM.Options.RangeFrameUpdates == "Fast" then
  382. updateRate = 0.05
  383. end]]
  384. local frame = CreateFrame("GameTooltip", "DBMRangeCheck", UIParent, "GameTooltipTemplate")
  385. dropdownFrame = CreateFrame("Frame", "DBMRangeCheckDropdown", frame, "UIDropDownMenuTemplate")
  386. frame:SetFrameStrata("DIALOG")
  387. frame:SetPoint(DBM.Options.RangeFramePoint, UIParent, DBM.Options.RangeFramePoint, DBM.Options.RangeFrameX, DBM.Options.RangeFrameY)
  388. frame:SetHeight(64)
  389. frame:SetWidth(64)
  390. frame:EnableMouse(true)
  391. frame:SetToplevel(true)
  392. frame:SetMovable()
  393. GameTooltip_OnLoad(frame)
  394. frame:SetPadding(16)
  395. frame:RegisterForDrag("LeftButton")
  396. frame:SetScript("OnDragStart", function(self)
  397. if not DBM.Options.RangeFrameLocked then
  398. self:StartMoving()
  399. end
  400. end)
  401. frame:SetScript("OnDragStop", function(self)
  402. self:StopMovingOrSizing()
  403. ValidateFramePosition(self)
  404. local point, _, _, x, y = self:GetPoint(1)
  405. DBM.Options.RangeFrameX = x
  406. DBM.Options.RangeFrameY = y
  407. DBM.Options.RangeFramePoint = point
  408. end)
  409. frame:SetScript("OnUpdate", function(self, e)
  410. elapsed = elapsed + e
  411. if elapsed >= 0.04 and self.checkFunc then
  412. onUpdate(self, elapsed)
  413. elapsed = 0
  414. end
  415. end)
  416. frame:SetScript("OnMouseDown", function(self, button)
  417. if button == "RightButton" then
  418. UIDropDownMenu_Initialize(dropdownFrame, initializeDropdown, "MENU")
  419. ToggleDropDownMenu(1, nil, dropdownFrame, "cursor", 5, -10)
  420. end
  421. end)
  422. return frame
  423. end
  424.  
  425. function createRadarFrame()
  426. local elapsed = 0
  427. local radarFrame = CreateFrame("Frame", "DBMRangeCheckRadar", UIParent)
  428. radarFrame:SetFrameStrata("DIALOG")
  429.  
  430. radarFrame:SetPoint(DBM.Options.RangeFrameRadarPoint, UIParent, DBM.Options.RangeFrameRadarPoint, DBM.Options.RangeFrameRadarX, DBM.Options.RangeFrameRadarY)
  431. radarFrame:SetHeight(128)
  432. radarFrame:SetWidth(128)
  433. radarFrame:EnableMouse(true)
  434. radarFrame:SetToplevel(true)
  435. radarFrame:SetMovable()
  436. radarFrame:RegisterForDrag("LeftButton")
  437. radarFrame:SetScript("OnDragStart", function(self)
  438. if not DBM.Options.RangeFrameLocked then
  439. self:StartMoving()
  440. end
  441. end)
  442. radarFrame:SetScript("OnDragStop", function(self)
  443. self:StopMovingOrSizing()
  444. ValidateFramePosition(self)
  445. local point, _, _, x, y = self:GetPoint(1)
  446. DBM.Options.RangeFrameRadarX = x
  447. DBM.Options.RangeFrameRadarY = y
  448. DBM.Options.RangeFrameRadarPoint = point
  449. end)
  450. radarFrame:SetScript("OnUpdate", function(self, e)
  451. elapsed = elapsed + e
  452. if elapsed >= 0.04 then
  453. onUpdateRadar(self, elapsed)
  454. elapsed = 0
  455. end
  456. end)
  457. radarFrame:SetScript("OnMouseDown", function(self, button)
  458. if button == "RightButton" then
  459. UIDropDownMenu_Initialize(dropdownFrame, initializeDropdown, "MENU")
  460. ToggleDropDownMenu(1, nil, dropdownFrame, "cursor", 5, -10)
  461. end
  462. end)
  463.  
  464. local bg = radarFrame:CreateTexture(nil, "BACKGROUND")
  465. bg:SetAllPoints(radarFrame)
  466. bg:SetBlendMode("BLEND")
  467. bg:SetTexture(0, 0, 0, 0.3)
  468. radarFrame.background = bg
  469.  
  470. local circle = radarFrame:CreateTexture(nil, "ARTWORK")
  471. circle:SetPoint("CENTER")
  472. circle:SetTexture("Interface\\AddOns\\DBM-Core\\textures\\radar_circle.blp")
  473. circle:SetBlendMode("ADD")
  474. radarFrame.circle = circle
  475.  
  476. local player = radarFrame:CreateTexture(nil, "OVERLAY")
  477. player:SetSize(32, 32)
  478. player:SetTexture("Interface\\Minimap\\MinimapArrow.blp")
  479. player:SetBlendMode("ADD")
  480. player:SetPoint("CENTER")
  481.  
  482. local text = radarFrame:CreateFontString(nil, "OVERLAY","GameTooltipText")
  483. text:SetWidth(128)
  484. text:SetHeight(15)
  485. text:SetPoint("BOTTOMLEFT", radarFrame, "TOPLEFT", 0,0)
  486. -- text:SetFont("Fonts\\FRIZQT__.TTF", 11)
  487. text:SetTextColor(1, 1, 1, 1)
  488. text:Show()
  489. radarFrame.text = text
  490.  
  491. -- for i=1, 40 do
  492. -- local dot = CreateFrame("Frame", "DBMRangeCheckRadarDot"..i, radarFrame, "WorldMapPartyUnitTemplate")
  493. -- dot:SetWidth(24)
  494. -- dot:SetHeight(24)
  495. -- dot:SetFrameStrata("TOOLTIP")
  496. -- dot:Hide()
  497. -- dots[i] = {dot = dot}
  498. -- end
  499. for i=1, 8 do
  500. local charm = radarFrame:CreateTexture("DBMRangeCheckRadarCharm"..i, "OVERLAY")
  501. charm:SetTexture("interface\\targetingframe\\UI-RaidTargetingIcons.blp")
  502. charm:SetWidth(16)
  503. charm:SetHeight(16)
  504. charm:SetTexCoord(
  505. CHARM_TEX_COORDS[i][1],
  506. CHARM_TEX_COORDS[i][2],
  507. CHARM_TEX_COORDS[i][3],
  508. CHARM_TEX_COORDS[i][4]
  509. )
  510. charm:Hide()
  511. charms[i] = charm
  512. end
  513.  
  514. radarFrame:Hide()
  515. return radarFrame
  516. end
  517.  
  518. ----------------
  519. -- OnUpdate --
  520. ----------------
  521. local soundUpdate = 0
  522. function onUpdate(self, elapsed)
  523. local color
  524. local j = 0
  525. self:ClearLines()
  526. self:SetText(DBM_CORE_RANGECHECK_HEADER:format(self.range), 1, 1, 1)
  527. if initRangeCheck(self.range) then
  528. if GetNumRaidMembers() > 0 then
  529. for i = 1, GetNumRaidMembers() do
  530. local uId = "raid"..i
  531. if not UnitIsUnit(uId, "player") and not UnitIsDeadOrGhost(uId) and self.checkFunc(uId, self.range) and (not self.filter or self.filter(uId)) then
  532. j = j + 1
  533. color = RAID_CLASS_COLORS[select(2, UnitClass(uId))] or NORMAL_FONT_COLOR
  534. local icon = GetRaidTargetIndex(uId)
  535. local text = icon and ("|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_%d:0|t %s"):format(icon, UnitName(uId)) or UnitName(uId)
  536. self:AddLine(text, color.r, color.g, color.b)
  537. if j >= 5 then
  538. break
  539. end
  540. end
  541. end
  542. elseif GetNumPartyMembers() > 0 then
  543. for i = 1, GetNumPartyMembers() do
  544. local uId = "party"..i
  545. if not UnitIsUnit(uId, "player") and not UnitIsDeadOrGhost(uId) and self.checkFunc(uId, self.range) and (not self.filter or self.filter(uId)) then
  546. j = j + 1
  547. color = RAID_CLASS_COLORS[select(2, UnitClass(uId))] or NORMAL_FONT_COLOR
  548. local icon = GetRaidTargetIndex(uId)
  549. local text = icon and ("|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_%d:0|t %s"):format(icon, UnitName(uId)) or UnitName(uId)
  550. self:AddLine(text, color.r, color.g, color.b)
  551. if j >= 5 then
  552. break
  553. end
  554. end
  555. end
  556. end
  557. else
  558. self:AddLine(DBM_CORE_RANGE_CHECK_ZONE_UNSUPPORTED:format(self.range))
  559. end
  560. soundUpdate = soundUpdate + elapsed
  561. if soundUpdate >= 5 and j > 0 then
  562. updateSound(j)
  563. soundUpdate = 0
  564. end
  565. self:Show()
  566. end
  567.  
  568. do
  569. local rotation, pixelsperyard, prevNumPlayers, range, isInSupportedArea
  570. local function createDot(id)
  571. local dot = CreateFrame("Frame", "DBMRangeCheckRadarDot"..id, radarFrame, "WorldMapPartyUnitTemplate")
  572. dot:SetFrameStrata("TOOLTIP")
  573. dot:SetWidth(24)
  574. dot:SetHeight(24)
  575. dot:Hide()
  576.  
  577. dots[id].dot = dot -- store the dot so we can use it later again
  578. return dot
  579. end
  580.  
  581. local function setDotColor(id, class)
  582. if class and class == dots[id].class then return end
  583. if not class then class = "PRIEST" end -- if class=nil -> use white dots (priest)
  584. dots[id].dot.icon:SetTexCoord(
  585. BLIP_TEX_COORDS[class][1],
  586. BLIP_TEX_COORDS[class][2],
  587. BLIP_TEX_COORDS[class][3],
  588. BLIP_TEX_COORDS[class][4]
  589. )
  590. dots[id].class = class
  591. end
  592.  
  593. local function setDot(id, icon, filtered)
  594. local dot = dots[id].dot or createDot(id) -- load the dot, or create a new one if none exists yet (creating new probably never happens as the dots are created when the frame is created)
  595. local x = dots[id].x
  596. local y = dots[id].y
  597. local range = (x*x + y*y) ^ 0.5
  598. if range < (1.5 * frame.range) then -- if person is closer than 1.5 * range, show the dot. Else hide it
  599. local dx = ((x * math.cos(rotation)) - (-y * math.sin(rotation))) * pixelsperyard -- Rotate the X,Y based on player facing
  600. local dy = ((x * math.sin(rotation)) + (-y * math.cos(rotation))) * pixelsperyard
  601.  
  602. if icon and type(icon) == "number" and icon >= 1 and icon <= 8 then -- GetRaidTargetIndex seems to return strange values sometimes; see http://www.deadlybossmods.com/phpbb3/viewtopic.php?f=2&t=3213&p=30889#p30889
  603. if dots[id].icon and dots[id].icon ~= icon then
  604. charms[dots[id].icon]:Hide()
  605. end
  606. if not filtered then
  607. charms[icon]:ClearAllPoints()
  608. charms[icon]:SetPoint("CENTER", radarFrame, "CENTER", dx, dy)
  609. charms[icon]:Show()
  610. else
  611. charms[icon]:Hide()
  612. end
  613. dot:Hide()
  614. dots[id].icon = icon
  615. elseif not filtered then
  616. dot:ClearAllPoints()
  617. dot:SetPoint("CENTER", radarFrame, "CENTER", dx, dy)
  618. dot:Show()
  619. if dots[id].icon then
  620. charms[dots[id].icon]:Hide()
  621. dots[id].icon = nil
  622. end
  623. else
  624. if dots[id].icon and dots[id].icon ~= icon then
  625. charms[dots[id].icon]:Hide()
  626. dots[id].icon = nil
  627. end
  628. dot:Hide()
  629. end
  630. else
  631. dot:Hide()
  632. if dots[id].icon then
  633. charms[dots[id].icon]:Hide()
  634. dots[id].icon = nil
  635. end
  636. end
  637. if range < 1.10 * frame.range and not filtered then -- add an extra 10% in case of inaccuracy
  638. dots[id].tooClose = true
  639. else
  640. dots[id].tooClose = false
  641. end
  642. end
  643.  
  644. local breadthTimer = 0
  645.  
  646. function onUpdateRadar(self, elapsed)
  647. breadthTimer = breadthTimer + elapsed
  648. if initRangeCheck(frame.range) then--This is basically fixing a bug with map not being on right dungeon level half the time.
  649. pixelsperyard = min(radarFrame:GetWidth(), radarFrame:GetHeight()) / (frame.range * 3)
  650. radarFrame.circle:SetSize(frame.range * pixelsperyard * 2, frame.range * pixelsperyard * 2)
  651.  
  652. if frame.range ~= (range or 0) then
  653. range = frame.range
  654. radarFrame.text:SetText(DBM_CORE_RANGERADAR_HEADER:format(range))
  655. end
  656.  
  657. local mapName = GetMapInfo()
  658. local dims = DBM.MapSizes[mapName] and DBM.MapSizes[mapName][GetCurrentMapDungeonLevel()]
  659. if not dims then -- This ALWAYS happens when leaving a zone that has a map and moving into one that does not.
  660. if select(3, radarFrame.circle:GetVertexColor()) < 0.5 then
  661. radarFrame.circle:SetVertexColor(1,1,1)
  662. end
  663. for i, v in pairs(dots) do
  664. v.dot:Hide()
  665. end
  666. for i = 1, 8 do
  667. charms[i]:Hide()
  668. end
  669. else
  670. isInSupportedArea = true
  671. rotation = (2 * math.pi) - GetPlayerFacing()
  672. local numPlayers = 0
  673. local unitID = "raid%d"
  674. if GetNumRaidMembers() > 0 then
  675. unitID = "raid%d"
  676. numPlayers = GetNumRaidMembers()
  677. elseif GetNumPartyMembers() > 0 then
  678. unitID = "party%d"
  679. numPlayers = GetNumPartyMembers()
  680. end
  681. if numPlayers < (prevNumPlayers or 0) then
  682. for i=numPlayers, prevNumPlayers do
  683. if dots[i] then
  684. if dots[i].dot then
  685. dots[i].dot:Hide() -- Hide dots when people leave the group
  686. end
  687. dots[i].tooClose = false
  688. dots[i].icon = nil
  689. end
  690. end
  691. for i=1, 8 do
  692. charms[i]:Hide()
  693. end
  694. end
  695. prevNumPlayers = numPlayers
  696.  
  697. local playerX, playerY = GetPlayerMapPosition("player")
  698. if playerX == 0 and playerY == 0 then return end -- Somehow we can't get the correct position?
  699. ----------------------------
  700. local playersInRange = 0
  701. local playerNames = ''
  702. ----------------------------
  703. for i=1, numPlayers do
  704. local uId = unitID:format(i)
  705. ----------------------------
  706. if frame.checkFunc(uId, frame.range) then
  707. playersInRange = playersInRange + 1
  708. if i == numPlayers then
  709. playerNames = playerNames .. GetUnitName(uId)
  710. else
  711. playerNames = playerNames .. GetUnitName(uId) .. ', '
  712. end
  713. end
  714. ----------------------------
  715. if not UnitIsUnit(uId, "player") then
  716. local x,y = GetPlayerMapPosition(uId)
  717. if UnitIsDeadOrGhost(uId) then x = 100 end -- hack to make sure dead people aren't shown
  718. if not dots[i] then
  719. dots[i] = {
  720. icon = nil,
  721. class = "none",
  722. x = (x - playerX) * dims[1],
  723. y = (y - playerY) * dims[2]
  724. }
  725. else
  726. dots[i].x = (x - playerX) * dims[1]
  727. dots[i].y = (y - playerY) * dims[2]
  728. end
  729. setDot(i, GetRaidTargetIndex(uId), (frame.filter and not frame.filter(uId)))
  730. setDotColor(i, (select(2, UnitClass(uId))))
  731. else
  732. if dots[i] and dots[i].dot then
  733. dots[i].dot:Hide()
  734. end
  735. end
  736. end
  737.  
  738. ----------------------------
  739. if playersInRange > BREADTH_PLAYER_TOLERANCE then
  740. if breadthTimer > 1 then
  741. SendChatMessage(playersInRange.." players in "..frame.range.." yards! (".. playerNames ..")")
  742. breadthTimer = 0
  743. end
  744. end
  745. ----------------------------
  746.  
  747. local playerTooClose = false
  748. for i,v in pairs(dots) do
  749. if v.tooClose then
  750. playerTooClose = true
  751. break;
  752. end
  753. end
  754. if UnitIsDeadOrGhost("player") then
  755. radarFrame.circle:SetVertexColor(1,1,1)
  756. elseif playerTooClose then
  757. radarFrame.circle:SetVertexColor(1,0,0)
  758. else
  759. radarFrame.circle:SetVertexColor(0,1,0)
  760. end
  761. self:Show()
  762. end
  763. else
  764. if isInSupportedArea then
  765. -- we were in an area with known map dimensions during the last update but looks like we left it
  766. isInSupportedArea = false
  767. -- white frame
  768. radarFrame.circle:SetVertexColor(1,1,1)
  769. -- hide everything
  770. for i, v in pairs(dots) do
  771. v.dot:Hide()
  772. end
  773. for i = 1, 8 do
  774. charms[i]:Hide()
  775. end
  776. end
  777. end
  778. end
  779. end
  780.  
  781.  
  782. -----------------------
  783. -- Check functions --
  784. -----------------------
  785. checkFuncs[11] = function(uId)
  786. return CheckInteractDistance(uId, 2)
  787. end
  788.  
  789.  
  790. checkFuncs[10] = function(uId)
  791. return CheckInteractDistance(uId, 3)
  792. end
  793.  
  794. checkFuncs[28] = function(uId)
  795. return CheckInteractDistance(uId, 4)
  796. end
  797.  
  798.  
  799. local getDistanceBetween
  800. do
  801. local mapSizes = DBM.MapSizes
  802.  
  803. function getDistanceBetween(uId, x, y)
  804. local startX, startY = GetPlayerMapPosition(uId)
  805. local mapName = GetMapInfo()
  806. local dims = mapSizes[mapName] and mapSizes[mapName][GetCurrentMapDungeonLevel()]
  807. if not dims then
  808. return
  809. end
  810. local dX = (startX - x) * dims[1]
  811. local dY = (startY - y) * dims[2]
  812. return math.sqrt(dX * dX + dY * dY)
  813. end
  814.  
  815. local function mapRangeCheck(uId, range)
  816. return getDistanceBetween(uId, GetPlayerMapPosition("player")) < range
  817. end
  818.  
  819. function initRangeCheck(range)
  820. if checkFuncs[range] ~= mapRangeCheck then
  821. return true
  822. end
  823. local pX, pY = GetPlayerMapPosition("player")
  824. if pX == 0 and pY == 0 then
  825. SetMapToCurrentZone()
  826. pX, pY = GetPlayerMapPosition("player")
  827. end
  828. local levels = mapSizes[GetMapInfo()]
  829. if not levels then
  830. return false
  831. end
  832. local dims = levels[GetCurrentMapDungeonLevel()]
  833. if not dims and levels and GetCurrentMapDungeonLevel() == 0 then -- we are in a known zone but the dungeon level seems to be wrong
  834. SetMapToCurrentZone() -- fixes the dungeon level
  835. dims = levels[GetCurrentMapDungeonLevel()] -- try again
  836. if not dims then -- there is actually a level 0 in this zone but we don't know about it...too bad :(
  837. return false
  838. end
  839. elseif not dims then
  840. return false
  841. end
  842. return true -- everything ok!
  843. end
  844.  
  845. setmetatable(checkFuncs, {
  846. __index = function(t, k)
  847. return mapRangeCheck
  848. end
  849. })
  850. end
  851.  
  852. do
  853. local bandages = {21991, 34721, 34722, 53049, 53050, 53051} -- you should have one of these bandages in your cache
  854.  
  855. checkFuncs[15] = function(uId)
  856. for i, v in ipairs(bandages) do
  857. if IsItemInRange(v, uId) == 1 then
  858. return true
  859. elseif IsItemInRange(v, uId) == 0 then
  860. return false
  861. end
  862. end
  863. end
  864. end
  865.  
  866. ---------------
  867. -- Methods --
  868. ---------------
  869. function rangeCheck:Show(range, filter)
  870. SetMapToCurrentZone()--Set map to current zone before checking other stuff, work around annoying bug i hope?
  871. if type(range) == "function" then -- the first argument is optional
  872. return self:Show(nil, range)
  873. end
  874. local mapName = GetMapInfo()
  875. range = range or 10
  876. frame = frame or createFrame()
  877. radarFrame = radarFrame or createRadarFrame()
  878. frame.checkFunc = checkFuncs[range] or error(("Range \"%d yd\" is not supported."):format(range), 2)
  879. frame.range = range
  880. frame.filter = filter
  881. if DBM.Options.RangeFrameFrames == "text" or DBM.Options.RangeFrameFrames == "both" or DBM.MapSizes[mapName] == nil or (DBM.MapSizes[mapName] and DBM.MapSizes[mapName][GetCurrentMapDungeonLevel()] == nil) then
  882. frame:Show()
  883. frame:SetOwner(UIParent, "ANCHOR_PRESERVE")
  884. onUpdate(frame, 0)
  885. end
  886. if (DBM.Options.RangeFrameFrames == "radar" or DBM.Options.RangeFrameFrames == "both") and (DBM.MapSizes[mapName] and DBM.MapSizes[mapName][GetCurrentMapDungeonLevel()] ~= nil) then
  887. onUpdateRadar(radarFrame, 1)
  888. end
  889. end
  890.  
  891. function rangeCheck:Hide()
  892. if frame then frame:Hide() end
  893. if radarFrame then radarFrame:Hide() end
  894. end
  895.  
  896. function rangeCheck:IsShown()
  897. return frame and frame:IsShown() or radarFrame and radarFrame:IsShown()
  898. end
  899.  
  900. function rangeCheck:GetDistance(...)
  901. if initRangeCheck() then
  902. return getDistanceBetween(...)
  903. end
  904. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement