Advertisement
Guest User

_Cursor.lua bugfix

a guest
Feb 14th, 2015
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.39 KB | None | 0 0
  1. -------------------------------------------------------------------------------
  2. -- Localized Lua globals.
  3. -------------------------------------------------------------------------------
  4. local _G = getfenv(0)
  5.  
  6. -- Functions
  7. local next = _G.next
  8. local pairs = _G.pairs
  9. local tonumber = _G.tonumber
  10. local type = _G.type
  11.  
  12. -- Libraries
  13. local table = _G.table
  14.  
  15. -------------------------------------------------------------------------------
  16. -- AddOn namespace.
  17. -------------------------------------------------------------------------------
  18. local FOLDER_NAME = ...
  19. local Version = GetAddOnMetadata(FOLDER_NAME, "Version"):match("^([%d.]+)")
  20. _CursorOptions = nil
  21. _CursorOptionsCharacter = {
  22. Cursors = {},
  23. Version = Version
  24. }
  25.  
  26. local L = _CursorLocalization
  27. local NS = CreateFrame("Frame", "_Cursor")
  28.  
  29. -------------------------------------------------------------------------------
  30. -- Variables
  31. -------------------------------------------------------------------------------
  32. local ActiveModels = {}
  33. local InactiveModels = {}
  34.  
  35. -------------------------------------------------------------------------------
  36. -- Constants
  37. -------------------------------------------------------------------------------
  38. NS.DefaultModelSet = L.SETS["Energy beam"]
  39. NS.DefaultType = ""
  40. NS.DefaultValue = "spells\\errorcube" -- Used when cursor preset not found
  41. NS.ScaleDefault = 0.01 -- Baseline scaling factor applied before presets and custom scales
  42.  
  43. -- Set strings formatted as follows:
  44. -- "Name|[Enabled]|Strata|[Type]|Value[|Scale][|Facing][|X][|Y]"
  45. NS.DefaultSets = {
  46. [L.SETS["Energy beam"]] = {
  47. -- Energy/lightning trail
  48. L.CURSORS["Layer 1"] .. "|1|TOOLTIP|Trail|Electric, blue",
  49. L.CURSORS["Layer 2"] .. "|1|FULLSCREEN_DIALOG|Particle|Fire, blue",
  50. L.CURSORS["Layer 3"] .. "||FULLSCREEN_DIALOG"
  51. },
  52. [L.SETS["Shadow trail"]] = {
  53. -- Cloudy shadow trail
  54. L.CURSORS["Layer 1"] .. "|1|TOOLTIP|Trail|Shadow|0.5",
  55. L.CURSORS["Layer 2"] .. "|1|FULLSCREEN_DIALOG|Particle|Shadow cloud",
  56. L.CURSORS["Layer 3"] .. "||FULLSCREEN_DIALOG",
  57. },
  58. [L.SETS["Face Melter (Warning, bright!)"]] = {
  59. -- Large red blowtorch
  60. L.CURSORS["Laser"] .. "|1|LOW||spells\\cthuneeyeattack|1.5|.4|32|13",
  61. L.CURSORS["Heat"] .. "|1|BACKGROUND||spells\\deathanddecay_area_base",
  62. L.CURSORS["Smoke"] .. "|1|BACKGROUND||spells\\sandvortex_state_base",
  63. }
  64. }
  65.  
  66. -- Preset strings formatted as follows:
  67. -- "Path[|Scale][|Facing][|X][|Y]"
  68. NS.Presets = {
  69. ["Glow"] = {
  70. ["Burning cloud, blue"] = "spells\\manafunnel_impact_chest|||4|-6",
  71. ["Burning cloud, green"] = "spells\\lifetap_state_chest|||4|-6",
  72. ["Burning cloud, purple"] = "spells\\soulfunnel_impact_chest|1|0|4|-6",
  73. ["Burning cloud, red"] = "spells\\healrag_state_chest|||4|-6",
  74. ["Cloud, black & blue"] = "spells\\enchantments\\soulfrostglow_high|4||8|-7",
  75. ["Cloud, blue"] = "spells\\enchantments\\spellsurgeglow_high|6||10|-8",
  76. ["Cloud, bright purple"] = "spells\\gouge_precast_state_hand|2.4||11|-9",
  77. ["Cloud, corruption"] = "spells\\seedofcorruption_state|.9||9|-8",
  78. ["Cloud, dark blue"] = "spells\\summon_precast_hand|2.7||9|-8",
  79. ["Cloud, executioner"] = "spells\\enchantments\\disintigrateglow_high|4||8|-7",
  80. ["Cloud, fire"] = "spells\\enchantments\\sunfireglow_high|5||10|-8",
  81. ["Cloud, frost"] = "spells\\icyenchant_high|8||8|-8",
  82. ["Ring, bloodlust"] = "spells\\bloodlust_state_hand|2.6||9|-8",
  83. ["Ring, bones"] = "spells\\bonearmor_state_chest|.8||12|-9",
  84. ["Ring, holy"] = "spells\\holy_precast_high_base|.8||9|-9",
  85. ["Ring, pulse blue"] = "spells\\brillianceaura|.8||8|-8",
  86. ["Ring, frost"] = "spells\\ice_precast_high_hand|1.9||11|-9",
  87. ["Ring, vengeance"] = "spells\\vengeance_state_hand|2||9|-8",
  88. ["Simple, black"] = "spells\\shadowmissile|2||5|-6",
  89. ["Simple, green"] = "spells\\nature_precast_chest|||8|-8",
  90. ["Simple, white"] = "spells\\enchantments\\whiteflame_low|4|5.3|10|-8",
  91. ["Weather, lightning"] = "spells\\goblin_weather_machine_lightning|1.3||10|-11",
  92. ["Weather, sun"] = "spells\\goblin_weather_machine_sunny|1.5|2.1|11|-9",
  93. ["Weather, snow"] = "spells\\goblin_weather_machine_snow|1.5|2.1|11|-9",
  94. ["Weather, cloudy"] = "spells\\goblin_weather_machine_cloudy|1.5|2.1|11|-9",
  95. },
  96. ["Particle"] = {
  97. ["Dust, arcane"] = "spells\\arcane_form_precast|1.1|.7|9|-11",
  98. ["Dust, embers"] = "spells\\fire_form_precast|1.1|.7|9|-11",
  99. ["Dust, holy"] = "spells\\holy_form_precast|1.1|.7|9|-11",
  100. ["Dust, ice shards"] = "spells\\frost_form_precast|1.1|.7|9|-11",
  101. ["Dust, shadow"] = "spells\\shadow_form_precast|1.1|.7|9|-11",
  102. ["Fire"] = "spells\\demolisher_missile||2.2|11|-11",
  103. ["Fire, blue"] = "spells\\fire_blue_precast_uber_hand|||6|-8",
  104. ["Fire, fel"] = "spells\\fel_fire_precast_hand|||6|-8",
  105. ["Fire, orange"] = "spells\\fire_precast_uber_hand|1.5||4|-6",
  106. ["Fire, periodic red & blue"] = "spells\\incinerate_impact_base|.8||11|-10",
  107. ["Fire, wavy purple"] = "spells\\incinerateblue_low_base|.25|2.3|11|-10",
  108. ["Frost"] = "spells\\ice_precast_low_hand|2.5||8|-7",
  109. ["Lava burst"] = "spells\\shaman_lavaburst_missile|.8||9|-7",
  110. ["Leaves"] = "spells\\nature_form_precast|2.5|1|13|-11",
  111. ["Periodic glint"] = "spells\\enchantments\\sparkle_a|4",
  112. ["Plague cloud"] = "spells\\forsakencatapult_missile|1.5|2.3|10|-10",
  113. ["Shadow cloud"] = "spells\\cripple_state_chest|.5||8|-8",
  114. ["Spark, small white"] = "spells\\dispel_low_recursive|4",
  115. ["Spark, small blue"] = "spells\\detectmagic_recursive|4",
  116. ["Sparks, periodic healing"] = "spells\\lifebloom_state|||8|-8",
  117. ["Sparks, red"] = "spells\\immolationtrap_recursive|4",
  118. },
  119. ["Trail"] = {
  120. ["Blue"] = "spells\\beartrap|.9||5|-6",
  121. ["Electric, blue long"] = "spells\\lightningboltivus_missile|.1||4|-6",
  122. ["Electric, blue"] = "spells\\lightning_precast_low_hand|||4|-6",
  123. ["Electric, green"] = "spells\\lightning_fel_precast_low_hand|||4|-6",
  124. ["Electric, yellow"] = "spells\\wrath_precast_hand|1.5||4|-6",
  125. ["First-aid"] = "spells\\firstaid_hand|2||4|-6",
  126. ["Freedom"] = "spells\\blessingoffreedom_state|.4||8|-8",
  127. ["Ghost"] = "spells\\zig_missile|.7|1|8|-5",
  128. ["Holy bright"] = "spells\\holy_missile_uber|.9||11|-9",
  129. ["Long blue & holy glow"] = "spells\\alliancectfflag_spell|.9|2.3|1|-2",
  130. ["Shadow"] = "spells\\shadow_precast_uber_hand|||4|-6",
  131. ["Souls, small"] = "spells\\soulshatter_missile|1.7||5|-6",
  132. ["Souls"] = "spells\\wellofsouls_base|.5||9|-8",
  133. ["Sparkling, blue"] = "spells\\intervenetrail||2.4|7|-7",
  134. ["Sparkling, light green"] = "spells\\sprint_impact_chest|1.3|.8|3|-4",
  135. ["Sparkling, red"] = "spells\\chargetrail||2.4",
  136. ["Sparkling, white"] = "spells\\ribbontrail",
  137. ["Swirling, black"] = "spells\\shadow_impactdd_med_base|.5||5|-6",
  138. ["Swirling, blood"] = "spells\\bloodbolt_chest|.5||5|-6",
  139. ["Swirling, blue"] = "spells\\banish_chest_blue|.5||11|-9",
  140. ["Swirling, holy"] = "spells\\holy_precast_uber_hand|||5|-6",
  141. ["Swirling, nature"] = "spells\\rejuvenation_impact_base|.35||5|-6",
  142. ["Swirling, poison"] = "spells\\banish_chest|.5||11|-9",
  143. ["Swirling, purple"] = "spells\\banish_chest_purple|.5||11|-9",
  144. ["Swirling, shadow"] = "spells\\banish_chest_dark|.5||11|-9",
  145. ["Swirling, white"] = "spells\\banish_chest_white|.5||11|-9",
  146. ["Swirling, yellow"] = "spells\\banish_chest_yellow|.5||11|-9",
  147. },
  148. ["Breath"] = {
  149. ["Arcane"] = "spells\\dragonbreath_arcane|.25|5.4",
  150. ["Fire. blue"] = "spells\\dragonbreath_frost|.25|5.4",
  151. ["Fire, fel"] = "spells\\fel_flamebreath|.5|5.5",
  152. ["Fire, purple"] = "spells\\dragonbreath_shadow|.25|5.4",
  153. ["Fire, red"] = "spells\\dragonbreath_fire|.25|5.4",
  154. ["Frost"] = "spells\\flamebreath_blue|.5|5.5",
  155. ["Frostfire"] = "spells\\flamebreathmff|.5|5.5",
  156. ["Smoke"] = "spells\\corrosivesandbreath|.5|5.5",
  157. }
  158. }
  159.  
  160. -------------------------------------------------------------------------------
  161. -- Helpers
  162. -------------------------------------------------------------------------------
  163. local AddHideCondition, RemoveHideCondition
  164. do
  165. local ActiveHideConditions = {}
  166.  
  167. function AddHideCondition(Name)
  168. if not ActiveHideConditions[Name] then
  169. ActiveHideConditions[Name] = true
  170. NS:Hide()
  171. end
  172. end
  173.  
  174. function RemoveHideCondition(Name)
  175. if ActiveHideConditions[Name] then
  176. ActiveHideConditions[Name] = nil
  177.  
  178. if next(ActiveHideConditions) == nil then
  179. NS:Show()
  180. end
  181. end
  182. end
  183. end
  184.  
  185. local function DisableModel(model)
  186. if not ActiveModels[model] then
  187. return
  188. end
  189. ActiveModels[model] = nil
  190. InactiveModels[model] = true
  191.  
  192. model.X = nil
  193. model.Y = nil
  194. model:Hide()
  195. model:ClearModel()
  196. end
  197.  
  198. local function EnableModel(model, cursorData)
  199. if ActiveModels[model] then
  200. DisableModel(model)
  201. end
  202. InactiveModels[model] = nil
  203. ActiveModels[model] = cursorData
  204.  
  205. local cursor = ActiveModels[model]
  206. local scale = (cursor.Scale or 1.0) * NS.ScaleDefault
  207. local facing = cursor.Facing or 0
  208.  
  209. model.X = cursor.X or 0
  210. model.Y = cursor.Y or 0
  211.  
  212. if #cursor.Type == 0 then -- Custom
  213. model:SetModel(cursor.Value .. ".mdx")
  214. else
  215. local presetType = NS.Presets[cursor.Type]
  216.  
  217. if not presetType or not presetType[cursor.Value] then
  218. cursor.Type = NS.DefaultType
  219. cursor.Value = NS.DefaultValue
  220. presetType = NS.Presets[cursor.Type]
  221. end
  222.  
  223. local path, scalePreset, facingPreset, x, y = ("|"):split(presetType[cursor.Value])
  224. model:SetModel(path .. ".mdx")
  225. model.X = model.X + (tonumber(x) or 0)
  226. model.Y = model.Y + (tonumber(y) or 0)
  227.  
  228. scale = scale * (tonumber(scalePreset) or 1.0)
  229. facing = facing + (tonumber(facingPreset) or 0)
  230. end
  231.  
  232. model:SetModelScale(scale)
  233. model:SetFacing(facing)
  234. model:SetFrameStrata(cursor.Strata)
  235. model:Show()
  236. end
  237.  
  238. -------------------------------------------------------------------------------
  239. -- Events
  240. -------------------------------------------------------------------------------
  241. NS:RegisterEvent("ADDON_LOADED")
  242. NS:RegisterEvent("CINEMATIC_START")
  243. NS:RegisterEvent("CINEMATIC_STOP")
  244. NS:RegisterEvent("SCREENSHOT_FAILED")
  245. NS:RegisterEvent("SCREENSHOT_SUCCEEDED")
  246.  
  247. function NS:SCREENSHOT_FAILED()
  248. RemoveHideCondition("Screenshot")
  249. end
  250.  
  251. NS.SCREENSHOT_SUCCEEDED = NS.SCREENSHOT_FAILED
  252.  
  253. function NS:CINEMATIC_START()
  254. AddHideCondition("Cinematic")
  255. end
  256.  
  257. function NS:CINEMATIC_STOP()
  258. RemoveHideCondition("Cinematic")
  259. end
  260.  
  261. do
  262. local function VersionCompare(Version1, Version2) -- Compares delimited version strings
  263. if Version1 == Version2 then
  264. return 0
  265. end
  266.  
  267. Version1 = {
  268. ("."):split(Version1 or "")
  269. }
  270.  
  271. Version2 = {
  272. ("."):split(Version2 or "")
  273. }
  274.  
  275. for index, Sub1 in ipairs(Version1) do
  276. local Sub2 = Version2[index]
  277. if not Sub2 or Sub1 > Sub2 then
  278. return 1
  279. elseif Sub1 < Sub2 then
  280. return -1
  281. end
  282. end
  283. return #Version1 - #Version2
  284. end
  285.  
  286. function NS:ADDON_LOADED(_, addonName)
  287. if addonName:lower() ~= FOLDER_NAME:lower() then
  288. return
  289. end
  290.  
  291. NS:UnregisterEvent("ADDON_LOADED")
  292. NS.ADDON_LOADED = nil
  293.  
  294. if not _CursorOptions then
  295. _CursorOptions = {
  296. Sets = CopyTable(NS.DefaultSets)
  297. }
  298. end
  299.  
  300. if _CursorOptions.Version ~= Version then
  301. if VersionCompare(_CursorOptions.Version, "3.1.0.2") < 0 then -- 3.1.0.2: Updated the Face Melter preset
  302. local Name = L.SETS["Face Melter (Warning, bright!)"]
  303.  
  304. if _CursorOptions.Sets[Name] then
  305. _CursorOptions.Sets[Name] = CopyTable(NS.DefaultSets[Name])
  306. end
  307. end
  308.  
  309. _CursorOptions.Version = Version
  310. end
  311.  
  312. _CursorOptionsCharacter.Version = Version
  313.  
  314. if not _CursorOptionsCharacter.Cursors[1] then
  315. NS.LoadSet(NS.DefaultSets[NS.DefaultModelSet])
  316. else
  317. NS:UpdateModels()
  318.  
  319. if NS.Options then
  320. NS.Options.Update()
  321. end
  322. end
  323. end
  324. end
  325.  
  326. -------------------------------------------------------------------------------
  327. -- Hooks.
  328. -------------------------------------------------------------------------------
  329. -- Hide during screenshots
  330. _G.hooksecurefunc("Screenshot", function()
  331. AddHideCondition("Screenshot")
  332. end)
  333.  
  334. -- Hide while FMV movies play
  335. _G.MovieFrame:HookScript("OnShow", function()
  336. AddHideCondition("Movie") -- FMV movie sequence, like the Wrathgate cinematic
  337. end)
  338.  
  339. _G.MovieFrame:HookScript("OnHide", function()
  340. RemoveHideCondition("Movie")
  341. end)
  342.  
  343. -------------------------------------------------------------------------------
  344. -- Scripts.
  345. -------------------------------------------------------------------------------
  346. do
  347. local UPDATE_INTERVAL = 1
  348.  
  349. local TotalElapsed = 0
  350. local IsMouselooking = _G.IsMouselooking
  351.  
  352. _G.CreateFrame("Frame"):SetScript("OnUpdate", function(self, elapsed)
  353. TotalElapsed = TotalElapsed + elapsed
  354.  
  355. if TotalElapsed >= UPDATE_INTERVAL then
  356. TotalElapsed = 0
  357.  
  358.  
  359. end
  360. end)
  361. end
  362.  
  363. NS:SetScript("OnEvent", function(self, eventName, ...)
  364. return self[eventName](self, eventName, ...)
  365. end)
  366.  
  367. NS:SetScript("OnShow", function()
  368. for model in pairs(ActiveModels) do
  369. local path = model:GetModel() -- Returns model table if unset
  370.  
  371. if type(path) == "string" then
  372. model:SetModel(path)
  373. end
  374. end
  375. end)
  376.  
  377. do
  378. local GetCursorPosition = _G.GetCursorPosition
  379. local hypotenuse = (_G.GetScreenWidth() ^ 2 + _G.GetScreenHeight() ^ 2) ^ 0.5 * _G.UIParent:GetEffectiveScale()
  380. local previousX, previousY
  381.  
  382. NS:SetScript("OnUpdate", function(self, elapsed)
  383. local cursorX, cursorY = GetCursorPosition()
  384. if cursorX == previousX and cursorY == previousY then
  385. return
  386. end
  387.  
  388. for model in pairs(ActiveModels) do
  389. model:SetPosition((cursorX + model.X) / hypotenuse, (cursorY + model.Y) / hypotenuse, 0)
  390. end
  391.  
  392. previousX = cursorX
  393. previousY = cursorY
  394. end)
  395. end
  396.  
  397. --[[****************************************************************************
  398. * Function: _Cursor.LoadSet *
  399. * Description: Unpacks a set into the current settings. *
  400. ****************************************************************************]]
  401. do
  402. local tempCursors = {}
  403.  
  404. function NS.LoadSet(set)
  405. local cursors = _CursorOptionsCharacter.Cursors
  406.  
  407. -- Unload tables
  408. for index = 1, #cursors do
  409. local cursor = cursors[index]
  410. cursors[index] = nil
  411. tempCursors[cursor] = true
  412. end
  413.  
  414. -- Unpack new data
  415. for index = 1, #set do
  416. local cursorData = set[index]
  417. local cursor = next(tempCursors) or {}
  418. tempCursors[cursor] = nil
  419.  
  420. cursor.Name, cursor.Enabled, cursor.Strata, cursor.Type, cursor.Value, cursor.Scale, cursor.Facing, cursor.X, cursor.Y = ("|"):split(cursorData)
  421. cursor.Enabled = #cursor.Enabled > 0
  422. cursor.Type = cursor.Type or ""
  423. cursor.Value = cursor.Value or ""
  424. cursor.Scale = tonumber(cursor.Scale)
  425. cursor.Facing = tonumber(cursor.Facing)
  426. cursor.X = tonumber(cursor.X)
  427. cursor.Y = tonumber(cursor.Y)
  428. cursors[index] = cursor
  429. end
  430.  
  431. NS:UpdateModels()
  432.  
  433. if NS.Options then
  434. NS.Options.Update()
  435. end
  436. end
  437. end
  438.  
  439. --[[****************************************************************************
  440. * Function: _Cursor.SaveSet *
  441. * Description: Packs a set from the current settings. *
  442. ****************************************************************************]]
  443. function NS.SaveSet(set)
  444. table.wipe(set)
  445.  
  446. local cursors = _CursorOptionsCharacter.Cursors
  447. for index = 1, #cursors do
  448. local cursorData = cursors[index]
  449.  
  450. set[index] = ("|"):join(cursorData.Name, cursorData.Enabled and 1 or "",
  451. cursorData.Strata, cursorData.Type, cursorData.Value, cursorData.Scale or "",
  452. cursorData.Facing or "", cursorData.X or "", cursorData.Y or ""):gsub("|+$", "")
  453. end
  454. end
  455.  
  456. do
  457. local ModelStrataLevels = {
  458. BACKGROUND = 0,
  459. LOW = 0,
  460. MEDIUM = 0,
  461. HIGH = 0,
  462. DIALOG = 0,
  463. FULLSCREEN = 0,
  464. FULLSCREEN_DIALOG = 0,
  465. TOOLTIP = 0
  466. }
  467.  
  468. function NS:UpdateModels()
  469. for Model in pairs(ActiveModels) do
  470. DisableModel(Model)
  471. end
  472.  
  473. for strataName in pairs(ModelStrataLevels) do
  474. ModelStrataLevels[strataName] = 0
  475. end
  476. local cursors = _CursorOptionsCharacter.Cursors
  477.  
  478. for index = 1, #cursors do
  479. local cursorData = cursors[index]
  480.  
  481. if cursorData.Enabled then
  482. local model = next(InactiveModels)
  483.  
  484. if not model then
  485. model = _G.CreateFrame("Model", nil, self)
  486. model:SetAllPoints(nil) -- Fullscreen
  487. model:Hide()
  488. model:SetLight(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) -- Allows trails like warriors' intervene to work
  489. end
  490. EnableModel(model, cursorData)
  491.  
  492. local strataLevel = ModelStrataLevels[cursorData.Strata] + 1
  493. ModelStrataLevels[cursorData.Strata] = strataLevel
  494. model:SetFrameLevel(strataLevel)
  495. end
  496. end
  497. end
  498. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement