annotate core.lua @ 29:34e70bd042b1 v1.06

More compatible with GatherMate_Sharing
author Aaron@Aaron-PC
date Mon, 23 Aug 2010 18:12:53 -0500
parents da9bbf7b08c7
children 0ea3ff6465de
rev   line source
Aaron@4 1 --[[--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))
Aaron@4 2
Aaron@4 3 RecipeProfit by -[@project-author@]-
Aaron@4 4
Aaron@4 5 Rev: @project-revision@
Aaron@4 6 Updated: @file-date-iso@
Aaron@4 7
Aaron@4 8 --))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))
Aaron@4 9
Aaron@22 10 URL:
Aaron@22 11 http://www.wrathguides.com/
Aaron@22 12
Aaron@22 13 License:
Aaron@22 14 This file is a part of "RecipeProfit for GatherMate."
Aaron@22 15
Aaron@22 16 This program is free software; you can redistribute it and/or
Aaron@22 17 modify it under the terms of the GNU General Public License
Aaron@22 18 as published by the Free Software Foundation, either version 3
Aaron@22 19 of the License, or (at your option) any later version.
Aaron@22 20
Aaron@22 21 This program is distributed in the hope that it will be useful,
Aaron@22 22 but WITHOUT ANY WARRANTY; without even the implied warranty of
Aaron@22 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Aaron@22 24 GNU General Public License for more details.
Aaron@22 25
Aaron@22 26 You should have received a copy of the GNU General Public License
Aaron@22 27 along with Foobar. If not, see <http://www.gnu.org/licenses/>.
Aaron@22 28
Aaron@22 29 Note:
Aaron@22 30 This program's source code is specifically designed to work with
Aaron@22 31 World of Warcraft's interpreted AddOn system.
Aaron@22 32
Aaron@22 33 You have an implicit license to use this program with these facilities
Aaron@22 34 since that is it's designated purpose as per:
Aaron@22 35 http://www.fsf.org/licensing/licenses/gpl-faq.html#InterpreterIncompat
Aaron@4 36
Aaron@4 37 --]]--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))
Aaron@4 38
Aaron@22 39
Aaron@12 40 local RecipeProfit = LibStub("AceAddon-3.0"):NewAddon("RecipeProfit", "AceEvent-3.0", "AceConsole-3.0")
Aaron@0 41 local GatherMate = LibStub("AceAddon-3.0"):GetAddon("GatherMate")
Aaron@0 42 local tabletest = {}
Aaron@16 43 local db = {}
Aaron@1 44 local safeRecipes = {}
Aaron@16 45 local ids = {}
Aaron@24 46 local nodeLookup = {}
Aaron@16 47
Aaron@17 48 local profile
Aaron@17 49
Aaron@0 50 RecipeProfit.db = db;
Aaron@0 51
Aaron@17 52 --[[ Forward Definitions (for local functions) ]]
Aaron@16 53 local get_faction_db,
Aaron@16 54 add_note,
Aaron@16 55 button_update,
Aaron@16 56 find_good_id,
Aaron@16 57 safe_cache_vendor,
Aaron@17 58 get_note_title,
Aaron@17 59 get_next_texture_id,
Aaron@17 60 set_node_constants,
Aaron@24 61 get_colored_note_name,
Aaron@17 62 inject_options;
Aaron@16 63
Aaron@17 64 --[[ Deep table inspection for debugging ]]
Aaron@0 65 function debugprint(val, indent)
Aaron@0 66 indent = indent or "";
Aaron@0 67 if not(type(val) == "table") then
Aaron@0 68 print("Not table: " .. val)
Aaron@0 69 return
Aaron@0 70 end
Aaron@0 71
Aaron@0 72 for k,v in pairs(val) do
Aaron@0 73 if(type(k) == "table" and type(v) == "table") then
Aaron@0 74 print(indent .. "table key: {")
Aaron@0 75 debugprint(k, indent .. " ")
Aaron@0 76 print(indent .. "} = {")
Aaron@0 77 debugprint(v, indent .. " ")
Aaron@0 78 print(indent .. "}")
Aaron@12 79 elseif(type(v) == "table") then
Aaron@0 80 print(indent .. k .. " = {")
Aaron@0 81 debugprint(v, indent .. " ")
Aaron@0 82 print(indent .. "}")
Aaron@0 83 else
Aaron@12 84 if(type(v) ~= "boolean") then
Aaron@12 85 print(indent .. k .. " = " .. v)
Aaron@12 86 else
Aaron@12 87 print(indent .. k .. " = " .. (v and "true" or "false"))
Aaron@12 88 end
Aaron@0 89 end
Aaron@0 90 end
Aaron@0 91 end
Aaron@8 92
Aaron@7 93 local defaultProfile = {
Aaron@7 94 ["show"] = {
Aaron@7 95 ["RecipeProfit"] = "always",
Aaron@7 96 ["Herb Gathering"] = "never",
Aaron@7 97 ["Extract Gas"] = "never",
Aaron@7 98 ["Fishing"] = "never",
Aaron@7 99 ["Mining"] = "never",
Aaron@7 100 ["Treasure"] = "never",
Aaron@7 101 },
Aaron@8 102 ["trackShow"] = "active",
Aaron@7 103 }
Aaron@0 104
Aaron@0 105 local options = {
Aaron@0 106 type = "group",
Aaron@0 107 name = "RecipeProfit", -- addon name to import from, don't localize
Aaron@0 108 handler = {},
Aaron@0 109 disabled = false,
Aaron@0 110 args = {
Aaron@1 111 opt = {
Aaron@0 112 order = 1,
Aaron@0 113 name = "Select Database",
Aaron@0 114 desc = "Show a different database",
Aaron@0 115 type = "group",
Aaron@0 116 guiInline = true,
Aaron@0 117 args = {
Aaron@0 118 faction = {
Aaron@0 119 order = 0,
Aaron@0 120 name = "Faction",
Aaron@0 121 desc = "Show a different database.",
Aaron@0 122 type = "select",
Aaron@0 123 values = {
Aaron@0 124 ["Alliance"] = "Alliance",
Aaron@0 125 ["Horde"] = "Horde",
Aaron@1 126 ["default"] = "Default",
Aaron@0 127 },
Aaron@0 128 arg = "faction",
Aaron@0 129 },
Aaron@1 130
Aaron@1 131 safeBuy = {
Aaron@1 132 order = 1,
Aaron@1 133 name = "Safe Recipe Buy",
Aaron@1 134 desc = "Warn when buying a recipe not on the RecipeProfit list.",
Aaron@1 135 type = "select",
Aaron@1 136 values = {
Aaron@7 137 --["on"] = "On",
Aaron@1 138 ["off"]= "Off",
Aaron@1 139 },
Aaron@1 140 arg = "safebuy",
Aaron@1 141 },
Aaron@0 142 },
Aaron@1 143 get = function(k) return db.profile[k.arg]; end,
Aaron@0 144 set = function(k, v) db.profile[k.arg] = v; RecipeProfit:DoMerge(); end,
Aaron@0 145 },
Aaron@0 146 loadData = {
Aaron@0 147 order = 8,
Aaron@0 148 name = "Import Data",
Aaron@0 149 desc = "Load RecipeProfit and import the data to your database.",
Aaron@0 150 type = "execute",
Aaron@0 151 func = function()
Aaron@0 152 RecipeProfit:DoMerge()
Aaron@0 153 end
Aaron@0 154 },
Aaron@7 155 loadProfile = {
Aaron@7 156 order = 9,
Aaron@7 157 name = "Load RecipeProfit Profile",
Aaron@7 158 desc = "Loads the RecipeProfit Profile into Gathermate for easy recipe tracking.",
Aaron@7 159 type = "execute",
Aaron@7 160 func = function()
Aaron@7 161 GatherMate.db.profiles["RecipeProfit"] = GatherMate.db.profiles["RecipeProfit"] or {}
Aaron@7 162 gmdb = GatherMate.db.profiles["RecipeProfit"]
Aaron@7 163 for k, v in pairs(defaultProfile) do
Aaron@7 164 gmdb[k] = v;
Aaron@7 165 end
Aaron@7 166 GatherMate:SendMessage("OnProfileChanged");
Aaron@7 167 GatherMate:GetModule("Config"):UpdateConfig()
Aaron@7 168 GatherMate:SendMessage("GatherMateConfigChanged")
Aaron@7 169 GatherMate.db:SetProfile("RecipeProfit")
Aaron@7 170 end
Aaron@7 171 },
Aaron@0 172 }
Aaron@0 173 }
Aaron@0 174
Aaron@0 175 local defaults = {
Aaron@1 176 faction = "default",
Aaron@1 177 safebuy = "on",
Aaron@16 178
Aaron@16 179 --submitting cached data not yet implemented
Aaron@16 180 enable_cache = false,
Aaron@16 181 location_cache = {},
Aaron@0 182 }
Aaron@0 183
Aaron@0 184 function RecipeProfit:OnInitialize()
Aaron@17 185 profile = RECIPEPROFIT_profile or defaults
Aaron@7 186
Aaron@1 187 for k, v in pairs(defaults) do
Aaron@1 188 profile[k] = profile[k] or v;
Aaron@1 189 end
Aaron@1 190
Aaron@12 191 self:RegisterChatCommand("recipeprofit", "ShowOptions")
Aaron@12 192 self:RegisterChatCommand("rp", "ShowOptions")
Aaron@12 193 self:RegisterChatCommand("profit", "ShowOptions")
Aaron@12 194
Aaron@0 195 db.profile = profile
Aaron@0 196 db.storage = {}
Aaron@0 197
Aaron@0 198 GatherMate:GetModule("Config"):RegisterModule("RecipeProfit", options)
Aaron@0 199 GatherMate:RegisterDBType("RecipeProfit", db.storage)
Aaron@8 200 GatherMate.db.profile.show["RecipeProfit"] = GatherMate.db.profile.show["RecipeProfit"] or "always"
Aaron@0 201
Aaron@17 202 set_node_constants()
Aaron@17 203 inject_options()
Aaron@8 204
Aaron@0 205 GatherMate:GetModule("Config"):UpdateConfig()
Aaron@0 206 GatherMate:GetModule("Config"):SendMessage("GatherMateConfigChanged")
Aaron@24 207
Aaron@24 208 --[[ hook GetNameForNode for custom highlighting ]]
Aaron@24 209 local oldFunction = GatherMate.GetNameForNode
Aaron@24 210
Aaron@24 211 GatherMate.GetNameForNode = function(lself, type, nodeID)
Aaron@24 212 if(type == "RecipeProfit") then
Aaron@24 213 return get_colored_note_name(lself, nodeID)
Aaron@24 214 else
Aaron@24 215 return oldFunction(lself, type, nodeID)
Aaron@24 216 end
Aaron@24 217 end
Aaron@24 218
Aaron@26 219 --[[ hook OnProfileChanged to fix cleanup database ]]
Aaron@26 220 local oldFunction2 = GatherMate.OnProfileChanged
Aaron@26 221
Aaron@26 222 GatherMate.OnProfileChanged = function(lself, ...)
Aaron@26 223 lself.db.profile.cleanupRange["RecipeProfit"] = lself.db.profile.cleanupRange["RecipeProfit"] or 15
Aaron@26 224 oldFunction2(lself, ...)
Aaron@26 225 end
Aaron@26 226
Aaron@0 227 end
Aaron@0 228
Aaron@17 229
Aaron@17 230 function RecipeProfit:OnEnable()
Aaron@17 231
Aaron@17 232 _G["MerchantPrevPageButton"]:HookScript("OnClick", self.UpdateButtons)
Aaron@17 233 _G["MerchantNextPageButton"]:HookScript("OnClick", self.UpdateButtons)
Aaron@17 234
Aaron@17 235 self:RegisterEvent("MERCHANT_SHOW", "UpdateButtons")
Aaron@17 236 self:RegisterEvent("MERCHANT_UPDATE", "UpdateButtons")
Aaron@17 237 self:RegisterEvent("BAG_UPDATE", "UpdateButtons")
Aaron@28 238
Aaron@17 239 RecipeProfit:DoMerge()
Aaron@17 240 end
Aaron@17 241
Aaron@12 242 function RecipeProfit:ShowOptions()
Aaron@13 243 LibStub("AceConfigDialog-3.0"):Open("GatherMate")
Aaron@13 244 LibStub("AceConfigDialog-3.0"):SelectGroup("GatherMate", "RecipeProfit")
Aaron@12 245 end
Aaron@12 246
Aaron@16 247 function RecipeProfit:UpdateButtons(event, ...)
Aaron@16 248 --print("UpdateButtons", event)
Aaron@28 249 if(WorldMapFrame:IsShown()) then
Aaron@28 250 local continent, zone = GetCurrentMapContinent(), GetCurrentMapZone()
Aaron@28 251 SetMapZoom(continent)
Aaron@28 252 SetMapZoom(continent, zone)
Aaron@28 253 else
Aaron@28 254 SetMapZoom(-1)
Aaron@28 255 end
Aaron@28 256
Aaron@28 257 GatherMate:GetModule("Display"):UpdateMaps()
Aaron@28 258
Aaron@16 259 if(not MerchantFrame:IsVisible()) then
Aaron@16 260 --print("UpdateButtons - (Event: ", event, ") - MerchantFrame not visible.");
Aaron@16 261 return;
Aaron@16 262 end
Aaron@16 263
Aaron@16 264 for i=1, MERCHANT_ITEMS_PER_PAGE, 1 do
Aaron@16 265 local buttonframe = _G["MerchantItem"..i];
Aaron@16 266 local index = (((MerchantFrame.page - 1) * MERCHANT_ITEMS_PER_PAGE) + i);
Aaron@16 267 --print(index)
Aaron@16 268 if index <= GetMerchantNumItems() then
Aaron@16 269 button_update(buttonframe)
Aaron@16 270 end
Aaron@16 271 end
Aaron@17 272 end
Aaron@16 273
Aaron@16 274 function RecipeProfit:DoMerge()
Aaron@16 275 ids = {}
Aaron@16 276 local selectedDB = get_faction_db();
Aaron@16 277
Aaron@16 278 GatherMate:ClearDB("RecipeProfit")
Aaron@16 279 for id, note in pairs(selectedDB) do
Aaron@16 280 x, y = find_good_id(note.x, note.y)
Aaron@16 281 add_note(x, y, note)
Aaron@16 282 end
Aaron@16 283
Aaron@16 284 GatherMate:SendMessage("GatherMateDataImport")
Aaron@16 285 GatherMate:GetModule("Config"):SendMessage("GatherMateConfigChanged")
Aaron@16 286 end
Aaron@16 287
Aaron@16 288 function get_note_title(note, factionTag)
Aaron@16 289 if(not factionTag) then
Aaron@16 290 _, factionTag = get_faction_db();
Aaron@16 291 end
Aaron@16 292
Aaron@16 293 return note.item.." - ("..note.vendor.." ".. factionTag ..")";
Aaron@16 294 end
Aaron@16 295
Aaron@16 296 function add_note(x, y, note)
Aaron@29 297 local coords = GatherMate:getID(x / 100, y / 100)
Aaron@29 298 local zoneID = GatherMate.zoneData[note.map][3]
Aaron@29 299 local nodeID = GatherMate.nodeIDs["RecipeProfit"][get_note_title(note, factionTag)]
Aaron@29 300 print(coords, zoneID, nodeID)
Aaron@29 301 GatherMate:InjectNode(zoneID, coords, "RecipeProfit", nodeID);
Aaron@16 302 end
Aaron@16 303
Aaron@16 304 function get_faction_db()
Aaron@16 305 local factionAlliance = db.profile.faction == "Alliance" or
Aaron@16 306 db.profile.faction == "default" and UnitFactionGroup("player") == "Alliance";
Aaron@16 307 if(factionAlliance) then
Aaron@16 308 return RECIPEPROFIT_alliance, "A";
Aaron@16 309 else
Aaron@16 310 return RECIPEPROFIT_horde, "H";
Aaron@16 311 end
Aaron@16 312 end
Aaron@16 313
Aaron@16 314 function safe_cache_vendor()
Aaron@16 315 if(not profile.enable_cache) then
Aaron@16 316 return
Aaron@16 317 end
Aaron@16 318
Aaron@16 319 if(not profile.location_cache[UnitName("NPC")]) then
Aaron@16 320 SetMapToCurrentZone()
Aaron@16 321 local pos = {}
Aaron@16 322 pos.x, pos.y = GetPlayerMapPosition("player")
Aaron@16 323 profile.location_cache[UnitName("NPC")] = pos
Aaron@16 324 end
Aaron@16 325 end
Aaron@15 326
Aaron@9 327 function button_update(self)
Aaron@9 328 local buttonName = _G[self:GetName().."Name"];
Aaron@9 329 local link = GetMerchantItemLink(_G[self:GetName().."ItemButton"]:GetID());
Aaron@9 330 if(not link) then
Aaron@9 331 return;
Aaron@9 332 end
Aaron@9 333
Aaron@9 334 local sName, sLink, iRarity, iLevel, iMinLevel, sType, sSubType, iStackCount = GetItemInfo(link)
Aaron@9 335
Aaron@16 336 if(sType == "Recipe" and safeRecipes[sName]) then
Aaron@16 337 safe_cache_vendor();
Aaron@9 338 SetItemButtonNameFrameVertexColor(self, 0, 0, 1.0);
Aaron@9 339 SetItemButtonSlotVertexColor(self, 0, 0, 0.5);
Aaron@9 340 buttonName:SetText("* " .. sName)
Aaron@28 341
Aaron@9 342 if(GetItemCount(link, true) == 0) then
Aaron@9 343 buttonName:SetTextColor(0,1,1);
Aaron@9 344 elseif(GetItemCount(link, true) < 5) then
Aaron@9 345 buttonName:SetTextColor(1,0,1);
Aaron@9 346 else
Aaron@9 347 buttonName:SetTextColor(1,0,0);
Aaron@9 348 end
Aaron@28 349
Aaron@9 350 else
Aaron@9 351 buttonName:SetTextColor(GameFontNormalSmall:GetTextColor());
Aaron@9 352 end
Aaron@9 353 end
Aaron@9 354
Aaron@16 355 function find_good_id(x, y)
Aaron@0 356 if ids[x.." "..y] then
Aaron@16 357 return find_good_id(x + .01, y)
Aaron@0 358 end
Aaron@0 359
Aaron@0 360 ids[x.." "..y] = true
Aaron@0 361 return x, y
Aaron@17 362 end
Aaron@17 363
Aaron@17 364 local lastNodeTextureId = 0;
Aaron@17 365
Aaron@17 366 function get_next_texture_id()
Aaron@17 367 lastNodeTextureId = lastNodeTextureId + 1;
Aaron@17 368 return lastNodeTextureId;
Aaron@17 369 end
Aaron@17 370
Aaron@17 371 function set_node_constants()
Aaron@17 372 GatherMate.nodeIDs["RecipeProfit"] = {}
Aaron@17 373 GatherMate.nodeTextures["RecipeProfit"] = {}
Aaron@17 374 GatherMate.nodeMinHarvest["RecipeProfit"] = {}
Aaron@17 375
Aaron@17 376 local nodes = GatherMate.nodeIDs["RecipeProfit"]
Aaron@17 377 for id, note in pairs(RECIPEPROFIT_alliance) do
Aaron@17 378 safeRecipes[note.item] = true;
Aaron@24 379 local id = get_next_texture_id();
Aaron@24 380 nodes[get_note_title(note, "A")] = id;
Aaron@24 381 nodeLookup[id] = note;
Aaron@17 382 end
Aaron@17 383
Aaron@17 384 for id, note in pairs(RECIPEPROFIT_horde) do
Aaron@17 385 safeRecipes[note.item] = true;
Aaron@24 386 local id = get_next_texture_id();
Aaron@24 387 nodes[get_note_title(note, "H")] = id;
Aaron@24 388 nodeLookup[id] = note;
Aaron@17 389 end
Aaron@17 390
Aaron@17 391 for i = 1, lastNodeTextureId, 1 do
Aaron@17 392 GatherMate.nodeTextures["RecipeProfit"][i] = "Interface\\Icons\\INV_Scroll_05"
Aaron@17 393 end
Aaron@17 394
Aaron@17 395 GatherMate.reverseNodeIDs["RecipeProfit"] = GatherMate:CreateReversedTable(nodes)
Aaron@17 396 end
Aaron@17 397
Aaron@17 398 function inject_options()
Aaron@17 399 GatherMate:GetModule("Config").options.args.display.args.general.args.showGroup.args["showRecipeProfit"] = {
Aaron@17 400 order = 6,
Aaron@17 401 name = "Show RecipeProfit nodes.",
Aaron@17 402 desc = "Toggle showing nodes added by RecipeProfit.",
Aaron@17 403 type = "select",
Aaron@17 404 values = {
Aaron@17 405 ["always"] = "Always show",
Aaron@17 406 ["never"] = "Never show",
Aaron@17 407 },
Aaron@17 408 arg = "RecipeProfit",
Aaron@17 409 }
Aaron@17 410
Aaron@17 411 GatherMate:GetModule("Config").options.args.display.args.general.args.iconGroup.args.tracking.args["showRecipeProfit"] = {
Aaron@17 412 order = 6.5,
Aaron@17 413 name = "RecipeProfit",
Aaron@17 414 desc = "Color of the tracking circle.",
Aaron@17 415 type = "color",
Aaron@17 416 hasAlpha = true,
Aaron@17 417 arg = "RecipeProfit",
Aaron@17 418 }
Aaron@17 419 end
Aaron@24 420
Aaron@24 421 function get_colored_note_name(self, nodeID)
Aaron@24 422 local text = self.reverseNodeIDs["RecipeProfit"][nodeID]
Aaron@24 423 local sName, sLink, iRarity, iLevel, iMinLevel, sType, sSubType, iStackCount = GetItemInfo(nodeLookup[nodeID].itementry)
Aaron@24 424
Aaron@24 425 if(not sLink) then
Aaron@24 426 return text
Aaron@24 427 end
Aaron@24 428
Aaron@24 429 local count = GetItemCount(sLink, true)
Aaron@24 430 local prefix = "|cFF888888(" .. count .. ") |cFF66DD66"
Aaron@24 431
Aaron@24 432 if(count == 0) then
Aaron@24 433 prefix = "|cFF00FFFF(" .. count .. ") |cFF66DD66"
Aaron@24 434 elseif(count >= 5) then
Aaron@24 435 prefix = "|cFFFF0000(" .. count .. ") |cFF66DD66"
Aaron@24 436 end
Aaron@24 437
Aaron@24 438 return prefix .. text
Aaron@24 439 end