annotate core.lua @ 27:85c7ff88e489

Added tag v1.05 for changeset 19e007e5eca9
author Aaron@Aaron-PC
date Sun, 22 Aug 2010 10:22:17 -0500
parents 19e007e5eca9
children da9bbf7b08c7
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@17 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@16 249 if(not MerchantFrame:IsVisible()) then
Aaron@16 250 --print("UpdateButtons - (Event: ", event, ") - MerchantFrame not visible.");
Aaron@16 251 return;
Aaron@16 252 end
Aaron@16 253
Aaron@16 254 for i=1, MERCHANT_ITEMS_PER_PAGE, 1 do
Aaron@16 255 local buttonframe = _G["MerchantItem"..i];
Aaron@16 256 local index = (((MerchantFrame.page - 1) * MERCHANT_ITEMS_PER_PAGE) + i);
Aaron@16 257 --print(index)
Aaron@16 258 if index <= GetMerchantNumItems() then
Aaron@16 259 button_update(buttonframe)
Aaron@16 260 end
Aaron@16 261 end
Aaron@17 262 end
Aaron@16 263
Aaron@16 264 function RecipeProfit:DoMerge()
Aaron@16 265 ids = {}
Aaron@16 266 local selectedDB = get_faction_db();
Aaron@16 267
Aaron@16 268 GatherMate:ClearDB("RecipeProfit")
Aaron@16 269 for id, note in pairs(selectedDB) do
Aaron@16 270 x, y = find_good_id(note.x, note.y)
Aaron@16 271 add_note(x, y, note)
Aaron@16 272 end
Aaron@16 273
Aaron@16 274 GatherMate:SendMessage("GatherMateDataImport")
Aaron@16 275 GatherMate:GetModule("Config"):SendMessage("GatherMateConfigChanged")
Aaron@16 276 end
Aaron@16 277
Aaron@16 278 function get_note_title(note, factionTag)
Aaron@16 279 if(not factionTag) then
Aaron@16 280 _, factionTag = get_faction_db();
Aaron@16 281 end
Aaron@16 282
Aaron@16 283 return note.item.." - ("..note.vendor.." ".. factionTag ..")";
Aaron@16 284 end
Aaron@16 285
Aaron@16 286 function add_note(x, y, note)
Aaron@16 287 GatherMate:AddNode(note.map, x / 100, y / 100, "RecipeProfit", get_note_title(note));
Aaron@16 288 end
Aaron@16 289
Aaron@16 290 function get_faction_db()
Aaron@16 291 local factionAlliance = db.profile.faction == "Alliance" or
Aaron@16 292 db.profile.faction == "default" and UnitFactionGroup("player") == "Alliance";
Aaron@16 293 if(factionAlliance) then
Aaron@16 294 return RECIPEPROFIT_alliance, "A";
Aaron@16 295 else
Aaron@16 296 return RECIPEPROFIT_horde, "H";
Aaron@16 297 end
Aaron@16 298 end
Aaron@16 299
Aaron@16 300 function safe_cache_vendor()
Aaron@16 301 if(not profile.enable_cache) then
Aaron@16 302 return
Aaron@16 303 end
Aaron@16 304
Aaron@16 305 if(not profile.location_cache[UnitName("NPC")]) then
Aaron@16 306 SetMapToCurrentZone()
Aaron@16 307 local pos = {}
Aaron@16 308 pos.x, pos.y = GetPlayerMapPosition("player")
Aaron@16 309 profile.location_cache[UnitName("NPC")] = pos
Aaron@16 310 end
Aaron@16 311 end
Aaron@15 312
Aaron@9 313 function button_update(self)
Aaron@9 314 local buttonName = _G[self:GetName().."Name"];
Aaron@9 315 local link = GetMerchantItemLink(_G[self:GetName().."ItemButton"]:GetID());
Aaron@9 316 if(not link) then
Aaron@9 317 return;
Aaron@9 318 end
Aaron@9 319
Aaron@9 320 local sName, sLink, iRarity, iLevel, iMinLevel, sType, sSubType, iStackCount = GetItemInfo(link)
Aaron@9 321
Aaron@16 322 if(sType == "Recipe" and safeRecipes[sName]) then
Aaron@16 323 safe_cache_vendor();
Aaron@9 324 SetItemButtonNameFrameVertexColor(self, 0, 0, 1.0);
Aaron@9 325 SetItemButtonSlotVertexColor(self, 0, 0, 0.5);
Aaron@9 326 buttonName:SetText("* " .. sName)
Aaron@9 327 if(GetItemCount(link, true) == 0) then
Aaron@9 328 buttonName:SetTextColor(0,1,1);
Aaron@9 329 elseif(GetItemCount(link, true) < 5) then
Aaron@9 330 buttonName:SetTextColor(1,0,1);
Aaron@9 331 else
Aaron@9 332 buttonName:SetTextColor(1,0,0);
Aaron@9 333 end
Aaron@9 334 else
Aaron@9 335 buttonName:SetTextColor(GameFontNormalSmall:GetTextColor());
Aaron@9 336 end
Aaron@9 337 end
Aaron@9 338
Aaron@16 339 function find_good_id(x, y)
Aaron@0 340 if ids[x.." "..y] then
Aaron@16 341 return find_good_id(x + .01, y)
Aaron@0 342 end
Aaron@0 343
Aaron@0 344 ids[x.." "..y] = true
Aaron@0 345 return x, y
Aaron@17 346 end
Aaron@17 347
Aaron@17 348 local lastNodeTextureId = 0;
Aaron@17 349
Aaron@17 350 function get_next_texture_id()
Aaron@17 351 lastNodeTextureId = lastNodeTextureId + 1;
Aaron@17 352 return lastNodeTextureId;
Aaron@17 353 end
Aaron@17 354
Aaron@17 355 function set_node_constants()
Aaron@17 356 GatherMate.nodeIDs["RecipeProfit"] = {}
Aaron@17 357 GatherMate.nodeTextures["RecipeProfit"] = {}
Aaron@17 358 GatherMate.nodeMinHarvest["RecipeProfit"] = {}
Aaron@17 359
Aaron@17 360 local nodes = GatherMate.nodeIDs["RecipeProfit"]
Aaron@17 361 for id, note in pairs(RECIPEPROFIT_alliance) do
Aaron@17 362 safeRecipes[note.item] = true;
Aaron@24 363 local id = get_next_texture_id();
Aaron@24 364 nodes[get_note_title(note, "A")] = id;
Aaron@24 365 nodeLookup[id] = note;
Aaron@17 366 end
Aaron@17 367
Aaron@17 368 for id, note in pairs(RECIPEPROFIT_horde) do
Aaron@17 369 safeRecipes[note.item] = true;
Aaron@24 370 local id = get_next_texture_id();
Aaron@24 371 nodes[get_note_title(note, "H")] = id;
Aaron@24 372 nodeLookup[id] = note;
Aaron@17 373 end
Aaron@17 374
Aaron@17 375 for i = 1, lastNodeTextureId, 1 do
Aaron@17 376 GatherMate.nodeTextures["RecipeProfit"][i] = "Interface\\Icons\\INV_Scroll_05"
Aaron@17 377 end
Aaron@17 378
Aaron@17 379 GatherMate.reverseNodeIDs["RecipeProfit"] = GatherMate:CreateReversedTable(nodes)
Aaron@17 380 end
Aaron@17 381
Aaron@17 382 function inject_options()
Aaron@17 383 GatherMate:GetModule("Config").options.args.display.args.general.args.showGroup.args["showRecipeProfit"] = {
Aaron@17 384 order = 6,
Aaron@17 385 name = "Show RecipeProfit nodes.",
Aaron@17 386 desc = "Toggle showing nodes added by RecipeProfit.",
Aaron@17 387 type = "select",
Aaron@17 388 values = {
Aaron@17 389 ["always"] = "Always show",
Aaron@17 390 ["never"] = "Never show",
Aaron@17 391 },
Aaron@17 392 arg = "RecipeProfit",
Aaron@17 393 }
Aaron@17 394
Aaron@17 395 GatherMate:GetModule("Config").options.args.display.args.general.args.iconGroup.args.tracking.args["showRecipeProfit"] = {
Aaron@17 396 order = 6.5,
Aaron@17 397 name = "RecipeProfit",
Aaron@17 398 desc = "Color of the tracking circle.",
Aaron@17 399 type = "color",
Aaron@17 400 hasAlpha = true,
Aaron@17 401 arg = "RecipeProfit",
Aaron@17 402 }
Aaron@17 403 end
Aaron@24 404
Aaron@24 405 function get_colored_note_name(self, nodeID)
Aaron@24 406 local text = self.reverseNodeIDs["RecipeProfit"][nodeID]
Aaron@24 407 local sName, sLink, iRarity, iLevel, iMinLevel, sType, sSubType, iStackCount = GetItemInfo(nodeLookup[nodeID].itementry)
Aaron@24 408
Aaron@24 409 if(not sLink) then
Aaron@24 410 return text
Aaron@24 411 end
Aaron@24 412
Aaron@24 413 local count = GetItemCount(sLink, true)
Aaron@24 414 local prefix = "|cFF888888(" .. count .. ") |cFF66DD66"
Aaron@24 415
Aaron@24 416 if(count == 0) then
Aaron@24 417 prefix = "|cFF00FFFF(" .. count .. ") |cFF66DD66"
Aaron@24 418 elseif(count >= 5) then
Aaron@24 419 prefix = "|cFFFF0000(" .. count .. ") |cFF66DD66"
Aaron@24 420 end
Aaron@24 421
Aaron@24 422 return prefix .. text
Aaron@24 423 end