---- Checks for a specific action slot whether the target is in range.-- If it is in range a message appears.---- by Bastian Pflieger <wb@illogical.de>-- -- Changes to make it working with 2.0:-- Line 234: "for slot in db.monitor do" into-- "for slot in pairs(db.monitor) do"-- Line 256: "if width[math.mod(i, db.columnCount)] < textwidth then" into-- "if width[math.fmod(i, db.columnCount)] < textwidth then"-- Line 257: "width[math.mod(i, db.columnCount)] = textwidth;" into-- "width[math.fmod(i, db.columnCount)] = textwidth;"-- Line 287: "getglobal("RangeCheckWatchFrameString" .. i):SetWidth(width[math.mod(i, db.columnCount)]);" into-- "getglobal("RangeCheckWatchFrameString" .. i):SetWidth(width[math.fmod(i, db.columnCount)]);"---- Last update: Dec 08, 2006---- supports "myAddOns 2.0": http://www.curse-gaming.com/mod.php?addid=358---- Main partlocal RANGECHECK_DISPLAY_TEXT = 1;local RANGECHECK_DISPLAY_WINDOW = 2;local RANGECHECK_DISPLAY_BOTH = RANGECHECK_DISPLAY_TEXT + RANGECHECK_DISPLAY_WINDOW;local db;local RangeCheckFontStrings;function RangeCheck_OnLoad() RangeCheckUsers = {}; RangeCheck_IsMoving = false; SlashCmdList["RANGECHECK"] = RangeCheck_ChatCommand; SLASH_RANGECHECK1 = "/rangecheck"; SLASH_RANGECHECK2 = "/rc"; this:RegisterEvent("PLAYER_TARGET_CHANGED"); this:RegisterEvent("ACTIONBAR_SLOT_CHANGED"); this:RegisterEvent("VARIABLES_LOADED"); -- fix for patch 1.10 RangeCheckTip:SetOwner(WorldFrame, "ANCHOR_NONE");endfunction RangeCheck_AddEntry(slot) slot = tonumber(slot); -- It seems that 'HasAction' returns true under certain circumstances, even if there is no action in slot. if slot >=1 and slot <= 108 and HasAction(slot) and db.monitor[slot] == nil then -- key: acton slot id, value: if already checked for current target db.monitor[slot] = false; db.monitorCount = db.monitorCount + 1; endendfunction RangeCheck_ChatCommand(msg) if msg == "" or msg == "help" or msg == "hilfe" or msg == "?" then for i = 1, table.getn(RANGECHECK_HELP) do RangeCheck_ChatMessage(RANGECHECK_HELP[i]); end elseif msg == "0" or msg == "off" or msg == "aus" then RangeCheck_Clear(); RangeCheck_PrintStatus(); RangeCheck_OnEvent("PLAYER_TARGET_CHANGED"); elseif msg == "status" then RangeCheck_PrintStatus(); elseif msg == "display" and not RangeCheck_IsMoving then RangeCheck_ToggleDisplay(); RangeCheck_OnEvent("PLAYER_TARGET_CHANGED"); RangeCheck_PrintStatus(); elseif msg == "lock" or msg == "unlock" then db.locked = (msg == "lock"); RangeCheck_PrintStatus(); elseif msg == "friendly" then db.monitorPlayers = not db.monitorPlayers; RangeCheck_PrintStatus(); elseif string.find(msg, "alpha") then RangeCheck_SetAlpha(msg); RangeCheck_PrintStatus(); elseif string.find(msg, "fontsize") then local _, _, newHeight = string.find(msg, "fontsize (%d+)"); if newHeight then newHeight = tonumber(newHeight); if newHeight > 0 and newHeight < 31 then RangeCheck_SetTextHeight(newHeight); RangeCheck_OnEvent("PLAYER_TARGET_CHANGED"); RangeCheck_PrintStatus(); else RangeCheck_ChatMessage(RANGECHECK_TEXTHEIGHT_ERROR); end else RangeCheck_ChatMessage(RANGECHECK_TEXTHEIGHT_ERROR); end elseif string.find(msg, "text") then local _, _, slot, text = string.find(msg, "text(%d+)%s?(.*)"); if slot and string.len(text) > 0 then db.customText[tonumber(slot)] = text; elseif slot then db.customText[tonumber(slot)] = nil; else RangeCheck_ChatMessage(RANGECHECK_CUSTOMTEXT_ERROR); end if slot then RangeCheck_OnEvent("PLAYER_TARGET_CHANGED"); RangeCheck_PrintStatus(); end elseif string.find(msg, "reset") then RangeCheckWatchFrame:ClearAllPoints(); RangeCheckWatchFrame:SetPoint("CENTER", UIParent, "CENTER"); elseif string.find(msg, "switch") then if db.columnCount == 1 then RangeCheck_SwitchCols(2); else RangeCheck_SwitchCols(1); end RangeCheck_PrintStatus(); elseif not RangeCheck_IsMoving and string.find(msg, "[%s%d]+") then RangeCheck_Clear(); string.gsub(msg, "%d+", RangeCheck_AddEntry); RangeCheck_OnEvent("PLAYER_TARGET_CHANGED"); RangeCheck_PrintStatus(); else RangeCheck_ChatMessage(RANGECHECK_UNKNOWN_COMMAND); endendfunction RangeCheck_OnEvent(event) RangeCheckFrame:Hide(); RangeCheckWatchFrame:Hide(); if (event == "PLAYER_TARGET_CHANGED" or event == "ACTIONBAR_SLOT_CHANGED" ) and RangeCheck_IsEnabled() and RangeCheck_IsValidTarget() then RangeCheck_Reset(); RangeCheck_SetupMonitorWindow(); RangeCheckFrame:Show(); end if event == "PLAYER_TARGET_CHANGED" and UnitName("target") == nil and RangeCheck_IsEnabled() and RangeCheck_IsOptionText() then UIErrorsFrame:AddMessage(" ", 1.0, 1.0, 0.0, 1.0, UIERRORS_HOLD_TIME); UIErrorsFrame:AddMessage(" ", 1.0, 1.0, 0.0, 1.0, UIERRORS_HOLD_TIME); UIErrorsFrame:AddMessage(" ", 1.0, 1.0, 0.0, 1.0, UIERRORS_HOLD_TIME); end if event == "VARIABLES_LOADED" then RangeCheck_SetupUser(); RangeCheck_SwitchCols(db.columnCount); RangeCheck_RegisterMyAddOns(); RangeCheckWatchFrameBG:SetAlpha(db.alpha); endendfunction RangeCheck_SetupUser() local databaseName = UnitName("player") .. "|" .. GetCVar("realmName"); --"AllCharacters"; if RangeCheckUsers[databaseName] == nil then RangeCheckUsers[databaseName] = { display = RANGECHECK_DISPLAY_BOTH, alpha = 0.25, locked = false, monitor = {}, monitorCount = 0 }; end db = RangeCheckUsers[databaseName]; -- New option to monitor friendly players if db.monitorPlayers == nil then db.monitorPlayers = false; end -- New option to set custom text if db.customText == nil then db.customText = {}; end -- New option to set text height if db.textHeight == nil then db.textHeight = 12; end -- New option to set column count if db.columnCount == nil then db.columnCount = 2; end RangeCheck_SetTextHeight(db.textHeight);endfunction RangeCheck_OnUpdate(elapsed) local allChecked = true; local inRange; for slot, alreadyChecked in pairs(db.monitor) do inRange = IsActionInRange(slot); -- Update monitor window if RangeCheckWatchFrame:IsVisible() and RangeCheckFontStrings[slot] then if inRange == nil then RangeCheckFontStrings[slot]:SetTextColor(0.7, 0.7, 0.7); elseif inRange == 1 then RangeCheckFontStrings[slot]:SetTextColor(0.0, 1.0, 0.0); else RangeCheckFontStrings[slot]:SetTextColor(1.0, 0.0, 0.0); end end -- Display text once if not alreadyChecked and RangeCheck_IsOptionText() then allChecked = false; if inRange == nil then db.monitor[slot] = true; elseif inRange == 1 then db.monitor[slot] = true; UIErrorsFrame:AddMessage(format(RANGECHECK_TARGET_IN_RANGE, RangeCheck_GetActionName(slot, true)), 1.0, 1.0, 0.0, 1.0, UIERRORS_HOLD_TIME); end else db.monitor[slot] = true; end end if allChecked and not RangeCheckWatchFrame:IsVisible() then this:Hide(); endendfunction RangeCheck_SortMonitorWindow(data1, data2) return string.lower(data1.name) < string.lower(data2.name);endfunction RangeCheck_SetupMonitorWindow() if not RangeCheck_IsOptionMonitorWindow() then RangeCheckWatchFrame:Hide(); return; end local fontString; local fontCount = 0; local width = {}; for i = 0, db.columnCount - 1 do width[i] = 1; end -- Sort monitored spells local spells = {} for slot in pairs(db.monitor) do if HasAction(slot) then table.insert(spells, {name = RangeCheck_GetActionName(slot), slot = slot}); end end table.sort(spells, RangeCheck_SortMonitorWindow); -- Reset Window RangeCheckFontStrings = {}; -- Show first ten spells in monitor window for i = 1, 10 do fontString = getglobal("RangeCheckWatchFrameString" .. i); if spells[i] then fontString:SetText(spells[i].name); fontString:Show(); -- save that fontString <-> slot association RangeCheckFontStrings[spells[i].slot] = fontString; -- Check if text width bigger than any other in this col local textwidth = RangeCheck_GetTextWidth(fontString:GetText()); if db.columnCount > 1 then if width[math.fmod(i, db.columnCount)] < textwidth then width[math.fmod(i, db.columnCount)] = textwidth; end elseif width[0] < textwidth then width[0] = textwidth; end -- fontCount = fontCount + 1; else fontString:SetText(""); fontString:Hide(); end end -- Adjust height and width if fontCount > 0 then RangeCheckWatchFrame:SetHeight(math.ceil(fontCount / db.columnCount) * 5 + math.ceil(fontCount / db.columnCount) * db.textHeight + 10); -- add width of all cols RangeCheckWatchFrame:SetWidth(0); for i = 0, db.columnCount - 1 do RangeCheckWatchFrame:SetWidth(RangeCheckWatchFrame:GetWidth() + width[i]); end -- make nice appearance if fontCount == 1 or db.columnCount == 1 then RangeCheckWatchFrame:SetWidth(RangeCheckWatchFrame:GetWidth() + 10); else RangeCheckWatchFrame:SetWidth(RangeCheckWatchFrame:GetWidth() + 20); end -- set all font obj to same size for i = 1, 10 do if db.columnCount > 1 then getglobal("RangeCheckWatchFrameString" .. i):SetWidth(width[math.fmod(i, db.columnCount)]); else getglobal("RangeCheckWatchFrameString" .. i):SetWidth(width[0]); end end RangeCheckWatchFrame:Show(); else RangeCheckWatchFrame:Hide(); endend-- Helpersfunction RangeCheck_SwitchCols(newColumnCount) db.columnCount = newColumnCount; for i = 2, 10 do getglobal("RangeCheckWatchFrameString" .. i):ClearAllPoints(); end if db.columnCount == 2 then -- old style 5 rows, 2 cols RangeCheckWatchFrameString2:SetPoint("TOPLEFT", RangeCheckWatchFrameString1, "TOPRIGHT", 10, 0); RangeCheckWatchFrameString3:SetPoint("TOPLEFT", RangeCheckWatchFrameString1, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString4:SetPoint("TOPLEFT", RangeCheckWatchFrameString2, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString5:SetPoint("TOPLEFT", RangeCheckWatchFrameString3, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString6:SetPoint("TOPLEFT", RangeCheckWatchFrameString4, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString7:SetPoint("TOPLEFT", RangeCheckWatchFrameString5, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString8:SetPoint("TOPLEFT", RangeCheckWatchFrameString6, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString9:SetPoint("TOPLEFT", RangeCheckWatchFrameString7, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString10:SetPoint("TOPLEFT", RangeCheckWatchFrameString8, "BOTTOMLEFT", 0, -5); else -- current display is one col RangeCheckWatchFrameString2:SetPoint("TOPLEFT", RangeCheckWatchFrameString1, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString3:SetPoint("TOPLEFT", RangeCheckWatchFrameString2, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString4:SetPoint("TOPLEFT", RangeCheckWatchFrameString3, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString5:SetPoint("TOPLEFT", RangeCheckWatchFrameString4, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString6:SetPoint("TOPLEFT", RangeCheckWatchFrameString5, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString7:SetPoint("TOPLEFT", RangeCheckWatchFrameString6, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString8:SetPoint("TOPLEFT", RangeCheckWatchFrameString7, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString9:SetPoint("TOPLEFT", RangeCheckWatchFrameString8, "BOTTOMLEFT", 0, -5); RangeCheckWatchFrameString10:SetPoint("TOPLEFT", RangeCheckWatchFrameString9, "BOTTOMLEFT", 0, -5); end -- show changes if RangeCheckWatchFrame:IsVisible() then RangeCheck_SetupMonitorWindow(); endendfunction RangeCheck_PrintStatus() if RangeCheck_IsEnabled() then -- print custom texts local sortHelper = {} for slot in pairs(db.customText) do table.insert(sortHelper, slot); end table.sort(sortHelper); for index, slot in ipairs(sortHelper) do RangeCheck_ChatMessage(format(RANGECHECK_CUSTOMTEXT, slot, db.customText[slot])); end -- print monitored slots local slots = nil; for slot in pairs(db.monitor) do if slots == nil then slots = slot; else slots = slots .. ", " .. slot; end end -- misc status if string.find(slots, ",") then RangeCheck_ChatMessage(format(RANGECHECK_STATUS1, slots)); else RangeCheck_ChatMessage(format(RANGECHECK_STATUS2, slots)); end if db.locked then RangeCheck_ChatMessage(format(RANGECHECK_DISPLAY[db.display], RANGECHECK_LOCKED, db.alpha, db.columnCount)); else RangeCheck_ChatMessage(format(RANGECHECK_DISPLAY[db.display], RANGECHECK_UNLOCKED, db.alpha, db.columnCount)); end RangeCheck_ChatMessage(RANGECHECK_MONITOR_PLAYERS[db.monitorPlayers]); RangeCheck_ChatMessage(format(RANGECHECK_TEXTHEIGHT, db.textHeight)); else RangeCheck_ChatMessage(RANGECHECK_STATUS3); endendfunction RangeCheck_Clear() db.monitor = {}; db.monitorCount = 0;endfunction RangeCheck_Reset() for slot in pairs(db.monitor) do db.monitor[slot] = false; endendfunction RangeCheck_IsLocked() return db.locked;endfunction RangeCheck_IsEnabled() return db.monitorCount ~= 0;endfunction RangeCheck_IsValidTarget() return UnitName("target") ~= nil and ( UnitCanAttack("player", "target") or (db.monitorPlayers and UnitPlayerControlled("target")) ) and UnitHealth("target") > 0;endfunction RangeCheck_IsOptionMonitorWindow() return ( db.display == RANGECHECK_DISPLAY_BOTH ) or ( db.display == RANGECHECK_DISPLAY_WINDOW );endfunction RangeCheck_IsOptionText() return ( db.display == RANGECHECK_DISPLAY_BOTH ) or ( db.display == RANGECHECK_DISPLAY_TEXT );endfunction RangeCheck_ToggleDisplay() if RangeCheck_IsOptionText() and RangeCheck_IsOptionMonitorWindow() then db.display = RANGECHECK_DISPLAY_TEXT; elseif RangeCheck_IsOptionText() then db.display = RANGECHECK_DISPLAY_WINDOW; else -- RangeCheck_IsOptionMonitorWindow() then db.display = RANGECHECK_DISPLAY_BOTH; endendfunction RangeCheck_GetActionName(slot, withRank) local spellName = ""; if db.customText[slot] then spellName = db.customText[slot]; else RangeCheckTip:SetAction(slot); if RangeCheckTipTextLeft1:GetText() ~= nil then spellName = RangeCheckTipTextLeft1:GetText(); if withRank and RangeCheckTipTextRight1:GetText() ~= nil then spellName = spellName .. " " .. RangeCheckTipTextRight1:GetText(); RangeCheckTipTextRight1:SetText(nil); end end end return spellName;endfunction RangeCheck_SetTextHeight(newHeight) db.textHeight = newHeight; for i = 1, 10 do getglobal("RangeCheckWatchFrameString" .. i):SetFont("Fonts\\FRIZQT__.TTF", newHeight); end RangeCheckWatchFrameWidthTest:SetFont("Fonts\\FRIZQT__.TTF", newHeight);endfunction RangeCheck_GetTextWidth(text) RangeCheckWatchFrameWidthTest:SetText(text); return RangeCheckWatchFrameWidthTest:GetWidth();endfunction RangeCheck_SetAlpha(msg) local startIndex, endIndex = string.find(msg, "[01].?%d?"); if startIndex then db.alpha = tonumber(string.sub(msg, startIndex, endIndex)); if db.alpha >= 1.0 then db.alpha = 1.0; elseif db.alpha <= 0.0 then db.alpha = 0.0; end RangeCheckWatchFrameBG:SetAlpha(db.alpha); endendfunction RangeCheck_RegisterMyAddOns() if myAddOnsFrame_Register then myAddOnsFrame_Register( { name = RANGECHECK_NAME, description = RANGECHECK_MYADDONS_DESCRIPTION, version = RANGECHECK_MYADDONS_VERSION, releaseDate = RANGECHECK_MYADDONS_RELEASEDATE, author = "wbb", email = "wb@illogical.de", website = "http://www.illogical.de", category = MYADDONS_CATEGORY_COMBAT, frame = "RangeCheckFrame" }, { RANGECHECK_MYADDONS_HELP1 .. "\n\n" .. RANGECHECK_HELP[1] .. "\n" .. RANGECHECK_HELP[2] .. "\n" .. RANGECHECK_HELP[3] .. "\n" .. RANGECHECK_HELP[4] .. "\n" .. RANGECHECK_HELP[5] .. "\n" .. RANGECHECK_HELP[6] .. "\n" .. RANGECHECK_HELP[7] .. "\n" .. RANGECHECK_HELP[8] .. "\n" .. RANGECHECK_HELP[9] .. "\n" .. RANGECHECK_HELP[10] .. "\n" .. RANGECHECK_HELP[11] .. "\n" .. RANGECHECK_HELP[12] }); endendfunction RangeCheck_ChatMessage(msg) DEFAULT_CHAT_FRAME:AddMessage("|cffffff00" .. RANGECHECK_NAME .. ": " .. msg);end