------------------------------------------------------------------------------- -- Waypoint.lua ------------------------------------------------------------------------------- -- File date: @file-date-iso@ -- File hash: @file-abbreviated-hash@ -- Project hash: @project-abbreviated-hash@ -- Project version: @project-version@ ------------------------------------------------------------------------------- -- Please see http://www.wowace.com/addons/arl/ for more information. ------------------------------------------------------------------------------- -- This source code is released under All Rights Reserved. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- Localized Lua globals. ------------------------------------------------------------------------------- local _G = getfenv(0) local table = _G.table local string = _G.string local pairs, select = _G.pairs, _G.select ------------------------------------------------------------------------------- -- AddOn namespace. ------------------------------------------------------------------------------- local FOLDER_NAME, private = ... local LibStub = _G.LibStub local addon = LibStub("AceAddon-3.0"):GetAddon(private.addon_name) local L = LibStub("AceLocale-3.0"):GetLocale(private.addon_name) local BFAC = LibStub("LibBabble-Faction-3.0"):GetLookupTable() local BZ = LibStub("LibBabble-Zone-3.0"):GetLookupTable() local A = private.acquire_types local F = private.filter_flags ------------------------------------------------------------------------------- -- Constants. ------------------------------------------------------------------------------- local KALIMDOR_NAMES = {} local EASTERN_KINGDOMS_NAMES = {} local OUTLAND_NAMES = {} local NORTHREND_NAMES = {} local KALIMDOR_IDNUMS = {} local EASTERN_KINGDOMS_IDNUMS = {} local OUTLAND_IDNUMS = {} local NORTHREND_IDNUMS = {} local function LoadZones(continent, zone, ...) -- Assign names to idnums for id = 1, select('#', ...), 1 do continent[id] = select(id, ...) end -- Reverse lookup to make work easier later on for id in pairs(continent) do zone[continent[id]] = id end end LoadZones(KALIMDOR_NAMES, KALIMDOR_IDNUMS, _G.GetMapZones(1)) LoadZones(EASTERN_KINGDOMS_NAMES, EASTERN_KINGDOMS_IDNUMS, _G.GetMapZones(2)) LoadZones(OUTLAND_NAMES, OUTLAND_IDNUMS, _G.GetMapZones(3)) LoadZones(NORTHREND_NAMES, NORTHREND_IDNUMS, _G.GetMapZones(4)) local INSTANCE_LOCATIONS = { [BZ["Ahn'kahet: The Old Kingdom"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["Dragonblight"]], ["continent"] = 4, ["x"] = 28.49, ["y"] = 51.73, }, [BZ["Auchenai Crypts"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Terokkar Forest"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["Azjol-Nerub"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["Dragonblight"]], ["continent"] = 4, ["x"] = 26.01, ["y"] = 50.83, }, [BZ["Blackrock Depths"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Searing Gorge"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["Blackrock Spire"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Searing Gorge"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["Blackwing Lair"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Searing Gorge"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["Dire Maul"]] = { ["zone"] = KALIMDOR_IDNUMS[BZ["Feralas"]], ["continent"] = 1, ["x"] = 0, ["y"] = 0, }, [BZ["Drak'Tharon Keep"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["Zul'Drak"]], ["continent"] = 4, ["x"] = 0, ["y"] = 0, }, [BZ["Gnomeregan"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Dun Morogh"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["Halls of Lightning"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["The Storm Peaks"]], ["continent"] = 4, ["x"] = 45.40, ["y"] = 21.37, }, [BZ["Halls of Stone"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["The Storm Peaks"]], ["continent"] = 4, ["x"] = 39.49, ["y"] = 26.92, }, [BZ["Karazhan"]] = { ["zone"] = KALIMDOR_IDNUMS[BZ["Deadwind Pass"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["Magisters' Terrace"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Isle of Quel'Danas"]], ["continent"] = 2, ["x"] = 61.20, ["y"] = 30.89, }, [BZ["Mana-Tombs"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Terokkar Forest"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["The Oculus"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["Borean Tundra"]], ["continent"] = 4, ["x"] = 27.52, ["y"] = 26.71, }, [BZ["Old Hillsbrad Foothills"]] = { ["zone"] = KALIMDOR_IDNUMS[BZ["Tanaris"]], ["continent"] = 1, ["x"] = 0, ["y"] = 0, }, [BZ["Onyxia's Lair"]] = { ["zone"] = KALIMDOR_IDNUMS[BZ["Dustwallow Marsh"]], ["continent"] = 1, ["x"] = 0, ["y"] = 0, }, [BZ["Ruins of Ahn'Qiraj"]] = { ["zone"] = KALIMDOR_IDNUMS[BZ["Silithus"]], ["continent"] = 1, ["x"] = 0, ["y"] = 0, }, [BZ["Scholomance"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Western Plaguelands"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["Sethekk Halls"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Terokkar Forest"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["Shadow Labyrinth"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Terokkar Forest"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["Stratholme"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Eastern Plaguelands"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["Temple of Ahn'Qiraj"]] = { ["zone"] = KALIMDOR_IDNUMS[BZ["Silithus"]], ["continent"] = 1, ["x"] = 0, ["y"] = 0, }, [BZ["The Arcatraz"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Netherstorm"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["The Black Morass"]] = { ["zone"] = KALIMDOR_IDNUMS[BZ["Tanaris"]], ["continent"] = 1, ["x"] = 0, ["y"] = 0, }, [BZ["The Botanica"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Netherstorm"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["The Deadmines"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Westfall"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["The Mechanar"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Netherstorm"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["The Nexus"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["Borean Tundra"]], ["continent"] = 4, ["x"] = 27.50, ["y"] = 25.97, }, [BZ["The Shattered Halls"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Hellfire Peninsula"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["The Slave Pens"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Zangarmarsh"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["The Steamvault"]] = { ["zone"] = OUTLAND_IDNUMS[BZ["Zangarmarsh"]], ["continent"] = 3, ["x"] = 0, ["y"] = 0, }, [BZ["The Temple of Atal'Hakkar"]] = { ["zone"] = EASTERN_KINGDOMS_IDNUMS[BZ["Swamp of Sorrows"]], ["continent"] = 2, ["x"] = 0, ["y"] = 0, }, [BZ["The Violet Hold"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["Dalaran"]], ["continent"] = 4, ["x"] = 66.78, ["y"] = 68.19, }, [BZ["Utgarde Keep"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["Howling Fjord"]], ["continent"] = 4, ["x"] = 57.28, ["y"] = 46.73, }, [BZ["Utgarde Pinnacle"]] = { ["zone"] = NORTHREND_IDNUMS[BZ["Howling Fjord"]], ["continent"] = 4, ["x"] = 57.26, ["y"] = 46.67, }, } local iconlist = {} -- Clears all the icons from the world map and the mini-map function addon:ClearWaypoints() if _G.TomTom and _G.TomTom.RemoveWaypoint then while iconlist[1] do _G.TomTom:RemoveWaypoint(table.remove(iconlist)) end elseif _G.Cartographer_Waypoints then while iconlist[1] do _G.Cartographer_Waypoints:CancelWaypoint(table.remove(iconlist)) end end end local CUSTOM_FILTERS = { "INSTANCE", "RAID", "WORLD_DROP", "MOB_DROP", } local CUSTOM_CHECKS = { ["maptrainer"] = "TRAINER", ["mapvendor"] = "VENDOR", ["mapquest"] = "QUEST", } local WAYPOINT_FUNCS = { [A.TRAINER] = function(id_num, recipe) if not addon.db.profile.maptrainer then return end local trainer = private.trainer_list[id_num] local trainer_faction = trainer.faction if trainer_faction == private.Player.faction or trainer_faction == "Neutral" then return trainer end end, [A.VENDOR] = function(id_num, recipe) if not addon.db.profile.mapvendor then return end local vendor = private.vendor_list[id_num] local vendor_faction = vendor.faction if vendor_faction == private.Player.faction or vendor_faction == "Neutral" then return vendor end end, [A.REPUTATION] = function(id_num, recipe) if not addon.db.profile.mapvendor then return end local vendor = private.vendor_list[id_num] local vendor_faction = vendor.faction if vendor_faction == private.Player.faction or vendor_faction == "Neutral" then return vendor end end, [A.MOB_DROP] = function(id_num, recipe) return addon.db.profile.mapmob and private.mob_list[id_num] end, [A.QUEST] = function(id_num, recipe) if not addon.db.profile.mapquest then return end local quest = private.quest_list[id_num] local quest_faction = quest.faction if quest_faction == private.Player.faction or quest_faction == "Neutral" then return quest end end, [A.CUSTOM] = function(id_num, recipe) local profile = addon.db.profile for field, flag in pairs(CUSTOM_CHECKS) do if profile[field] and recipe:HasFilter("common1", flag) then return private.custom_list[id_num] end end for index = 1, #CUSTOM_FILTERS do if recipe:HasFilter("common1", CUSTOM_FILTERS[index]) then return private.custom_list[id_num] end end end, } local TEXTURE_UP_FORMAT = ([[Interface\Addons\%s\img\]]):format(FOLDER_NAME) .. "%s_up" local current_waypoints = {} local function AddRecipeWaypoints(recipe_id, acquire_id, location_id, npc_id) local recipe = private.recipe_list[recipe_id] for acquire_type, acquire_info in pairs(recipe.acquire_data) do local waypoint_func = WAYPOINT_FUNCS[acquire_type] if waypoint_func and (not acquire_id or acquire_type == acquire_id) then for id_num, id_info in pairs(acquire_info) do if not npc_id or id_num == npc_id then if acquire_type == A.REPUTATION then for rep_level, level_info in pairs(id_info) do for vendor_id in pairs(level_info) do local waypoint = waypoint_func(vendor_id, recipe) if waypoint and (not location_id or waypoint.location == location_id) then waypoint.acquire_type = acquire_type current_waypoints[waypoint] = recipe_id end end end else local waypoint = waypoint_func(id_num, recipe) if waypoint and (not location_id or waypoint.location == location_id) then waypoint.acquire_type = acquire_type waypoint.reference_id = id_num current_waypoints[waypoint] = recipe_id end end end end end end end local function AddAllWaypoints(acquire_id, location_id, npc_id) local recipe_list = private.recipe_list local sorted_recipes = addon.sorted_recipes local editbox_text = addon.Frame.search_editbox:GetText() -- Scan through all recipes to display, and add the vendors to a list to get their acquire info for index = 1, #sorted_recipes do local recipe = recipe_list[sorted_recipes[index]] local matches_search = true if editbox_text ~= "" and editbox_text ~= _G.SEARCH then matches_search = recipe:HasState("RELEVANT") end if recipe:HasState("VISIBLE") and matches_search then for acquire_type, acquire_info in pairs(recipe.acquire_data) do local waypoint_func = WAYPOINT_FUNCS[acquire_type] if waypoint_func then for id_num, id_info in pairs(acquire_info) do if acquire_type == A.REPUTATION then for rep_level, level_info in pairs(id_info) do for vendor_id in pairs(level_info) do local waypoint = waypoint_func(vendor_id, recipe) if waypoint then waypoint.acquire_type = acquire_type current_waypoints[waypoint] = sorted_recipes[index] end end end else local waypoint = waypoint_func(id_num, recipe) if waypoint then waypoint.acquire_type = acquire_type waypoint.reference_id = id_num current_waypoints[waypoint] = sorted_recipes[index] end end end end end end end end -- Adds mini-map and world map icons with tomtom. -- Expected result: Icons are added to the world map and mini-map. -- Input: An optional recipe ID, acquire ID, and location ID. -- Output: Points are added to the maps function addon:AddWaypoint(recipe_id, acquire_id, location_id, npc_id) if not _G.TomTom and not _G.Cartographer_Waypoints then return end local worldmap = addon.db.profile.worldmap local minimap = addon.db.profile.minimap if not worldmap and not minimap then return end table.wipe(current_waypoints) if recipe_id then AddRecipeWaypoints(recipe_id, acquire_id, location_id, npc_id) elseif addon.db.profile.autoscanmap then AddAllWaypoints(acquire_id, location_id, npc_id) end local recipe_list = private.recipe_list for waypoint, spell_id in pairs(current_waypoints) do local name local x = waypoint.coord_x local y = waypoint.coord_y local location_name = waypoint.location or "nil" local continent, zone local recipe = recipe_list[spell_id] local _, _, _, quality_color = _G.GetItemQualityColor(recipe.quality) local acquire_str = private.acquire_strings[waypoint.acquire_type]:lower():gsub("_","") local color_code = private.category_colors[acquire_str] or "ffffff" if waypoint.acquire_type == A.QUEST then name = ("Quest: |cff%s%s|r (|c%s%s|r)"):format(color_code, private.quest_names[waypoint.reference_id], quality_color, recipe.name) else name = ("|cff%s%s|r (|c%s%s|r)"):format(color_code, waypoint.name or _G.UNKNOWN, quality_color, recipe.name) end waypoint.acquire_type = nil waypoint.reference_id = nil if KALIMDOR_IDNUMS[location_name] then continent = 1 zone = KALIMDOR_IDNUMS[location_name] elseif EASTERN_KINGDOMS_IDNUMS[location_name] then continent = 2 zone = EASTERN_KINGDOMS_IDNUMS[location_name] elseif OUTLAND_IDNUMS[location_name] then continent = 3 zone = OUTLAND_IDNUMS[location_name] elseif NORTHREND_IDNUMS[location_name] then continent = 4 zone = NORTHREND_IDNUMS[location_name] elseif INSTANCE_LOCATIONS[location_name] then local info = INSTANCE_LOCATIONS[location_name] zone = info.zone continent = info.continent x = info.x y = info.y name = ("%s (%s)"):format(name, location_name) else self:Debug("No continent/zone map match for recipe ID %d. Location: %s.", spell_id, location_name) end --@alpha@ if not x or not y or (x < -100) or (x > 100) or (y < -100) or (y > 100) then self:Debug("Invalid location coordinates for recipe ID %d. Location: %s.", spell_id, location_name) end --@end-alpha@ if zone and continent then if x == 0 and y == 0 and not INSTANCE_LOCATIONS[location_name] then self:Debug("Location is \"0, 0\" for recipe ID %d. Location: %s.", spell_id, location_name) end if _G.TomTom then local uid = _G.TomTom:AddZWaypoint(continent, zone, x, y, name, false, minimap, worldmap) table.insert(iconlist, uid) if _G.TomTom.ChangeWaypointIcon then local icon_tex -- Get the proper icon to put on the mini-map for index, profession in pairs(private.ordered_professions) do if index == self.Frame.profession then icon_tex = TEXTURE_UP_FORMAT:format(private.profession_textures[index]) break end end _G.TomTom:ChangeWaypointIcon(uid, minimap, worldmap, icon_tex) end elseif _G.Cartographer_Waypoints then local pt = _G.NotePoint:new(zone, x/100, y/100, name) _G.Cartographer_Waypoints:AddWaypoint(pt) table.insert(iconlist, pt.WaypointID) end else --@alpha@ if not zone then self:Debug("No zone for recipe ID %d. Location: %s.", spell_id, location_name) end if not continent then self:Debug("No continent for recipe ID %d. Location: %s.", spell_id, location_name) end --@end-alpha@ end end end