view core.lua @ 33:3976960cda3d v1.07

Fixed Chat Spew on startup. Thanks randomgrace of curse.com!
author Aaron Bregger
date Tue, 14 Sep 2010 11:12:28 -0500
parents 0ea3ff6465de
children 1e73cfb6f363
line wrap: on
line source
--[[--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))

    RecipeProfit by -[@project-author@]-
    
    Rev:     @project-revision@
    Updated: @file-date-iso@
    
--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))
    
    URL:
        http://www.wrathguides.com/
    
	License:
        This file is a part of "RecipeProfit for GatherMate."
        
		This program is free software; you can redistribute it and/or
		modify it under the terms of the GNU General Public License
		as published by the Free Software Foundation, either version 3
		of the License, or (at your option) any later version.

		This program is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
		GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

	Note:
		This program's source code is specifically designed to work with
		World of Warcraft's interpreted AddOn system.
        
		You have an implicit license to use this program with these facilities
		since that is it's designated purpose as per:
		http://www.fsf.org/licensing/licenses/gpl-faq.html#InterpreterIncompat
    
--]]--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))--))


local RecipeProfit = LibStub("AceAddon-3.0"):NewAddon("RecipeProfit", "AceEvent-3.0", "AceConsole-3.0")
local GatherMate = LibStub("AceAddon-3.0"):GetAddon("GatherMate")
local tabletest = {}
local db = {}
local safeRecipes = {}
local ids = {}
local nodeLookup = {}

local profile

RecipeProfit.db = db;

--[[ Forward Definitions (for local functions) ]]
local get_faction_db, 
      add_note, 
      button_update, 
      find_good_id, 
      safe_cache_vendor,
      get_note_title,
      get_next_texture_id,
      set_node_constants,
      get_colored_note_name,
      inject_options;

--[[ Deep table inspection for debugging ]]
function debugprint(val, indent)
    indent = indent or "";
    if not(type(val) == "table") then
        print("Not table: " .. val)
        return
    end
    
    for k,v in pairs(val) do
        if(type(k) == "table" and type(v) == "table") then
            print(indent .. "table key: {")
            debugprint(k, indent .. "    ")
            print(indent .. "} = {")
            debugprint(v, indent .. "    ")
            print(indent .. "}")
        elseif(type(v) == "table") then                
            print(indent .. k .. " = {")
            debugprint(v, indent .. "    ")
            print(indent .. "}") 
        else
            if(type(v) ~= "boolean") then
                print(indent .. k .. " = " .. v)
            else
                print(indent .. k .. " = " .. (v and "true" or "false"))
            end
        end
    end
end

local defaultProfile = {
    ["show"] = {
        ["RecipeProfit"] = "always",
        ["Herb Gathering"] = "never",
        ["Extract Gas"] = "never",
        ["Fishing"] = "never",
        ["Mining"] = "never",
        ["Treasure"] = "never",
    },
    ["trackShow"] = "active",
}

local options = {
 	type = "group",
	name = "RecipeProfit", -- addon name to import from, don't localize
	handler = {},
	disabled = false,
	args = {
        opt = {
            order = 1,
            name = "Select Database",
            desc = "Show a different database",
            type = "group",
            guiInline = true,
            args = {
                faction = {
                    order = 0,
                    name = "Faction",
                    desc = "Show a different database.",
                    type = "select",
                    values = {
                        ["Alliance"] = "Alliance",
                        ["Horde"]    = "Horde",
                        ["default"]  = "Default",
                    },
                    arg = "faction",
                },
                
                safeBuy = {
                    order = 1,
                    name = "Safe Recipe Buy",
                    desc = "Warn when buying a recipe not on the RecipeProfit list.",
                    type = "select",
                    values = {
                        --["on"] = "On",
                        ["off"]= "Off",
                    },
                    arg = "safebuy",
                },
            },
            get = function(k) return db.profile[k.arg]; end,
            set = function(k, v) db.profile[k.arg] = v; RecipeProfit:DoMerge(); end,
        },
		loadData = {
			order = 8,
			name = "Import Data",
			desc = "Load RecipeProfit and import the data to your database.",
			type = "execute",
			func = function() 
                RecipeProfit:DoMerge()
			end
        },
		loadProfile = {
			order = 9,
			name = "Load RecipeProfit Profile",
			desc = "Loads the RecipeProfit Profile into Gathermate for easy recipe tracking.",
			type = "execute",
			func = function() 
                GatherMate.db.profiles["RecipeProfit"] = GatherMate.db.profiles["RecipeProfit"] or {}
                gmdb = GatherMate.db.profiles["RecipeProfit"]
                for k, v in pairs(defaultProfile) do
                    gmdb[k] = v;
                end
                GatherMate:SendMessage("OnProfileChanged");
                GatherMate:GetModule("Config"):UpdateConfig()
                GatherMate:SendMessage("GatherMateConfigChanged")
                GatherMate.db:SetProfile("RecipeProfit")
			end
        },
    }
}

local defaults = {
    faction = "default",
    safebuy = "on",
    
    --submitting cached data not yet implemented
    enable_cache = false,
    location_cache = {},
}

function RecipeProfit:OnInitialize()
    profile = RECIPEPROFIT_profile or defaults
    
    for k, v in pairs(defaults) do
        profile[k] = profile[k] or v;
    end
    
    self:RegisterChatCommand("recipeprofit", "ShowOptions")
    self:RegisterChatCommand("rp",           "ShowOptions")
    self:RegisterChatCommand("profit",       "ShowOptions")
    
    db.profile = profile
    db.storage = {}
    
    GatherMate:GetModule("Config"):RegisterModule("RecipeProfit", options)
    GatherMate:RegisterDBType("RecipeProfit", db.storage)
    GatherMate.db.profile.show["RecipeProfit"] = GatherMate.db.profile.show["RecipeProfit"] or "always"
    
    set_node_constants()
    inject_options()
    
    GatherMate:GetModule("Config"):UpdateConfig()
    GatherMate:GetModule("Config"):SendMessage("GatherMateConfigChanged")
    
    --[[ hook GetNameForNode for custom highlighting ]]
    local oldFunction = GatherMate.GetNameForNode
    
    GatherMate.GetNameForNode = function(lself, type, nodeID)
        if(type == "RecipeProfit") then
            return get_colored_note_name(lself, nodeID)
        else
            return oldFunction(lself, type, nodeID)
        end
    end
    
    --[[ hook OnProfileChanged to fix cleanup database ]]
    local oldFunction2 = GatherMate.OnProfileChanged
    
    GatherMate.OnProfileChanged = function(lself, ...)
        lself.db.profile.cleanupRange["RecipeProfit"] = lself.db.profile.cleanupRange["RecipeProfit"] or 15
        oldFunction2(lself, ...)
    end
    
end

        
function RecipeProfit:OnEnable()

    _G["MerchantPrevPageButton"]:HookScript("OnClick", self.UpdateButtons)
    _G["MerchantNextPageButton"]:HookScript("OnClick", self.UpdateButtons)
    
    self:RegisterEvent("MERCHANT_SHOW",   "UpdateButtons")
    self:RegisterEvent("MERCHANT_UPDATE", "UpdateButtons")
    self:RegisterEvent("BAG_UPDATE",      "UpdateButtons")
  
    RecipeProfit:DoMerge()
end  

function RecipeProfit:ShowOptions()
    LibStub("AceConfigDialog-3.0"):Open("GatherMate")
    LibStub("AceConfigDialog-3.0"):SelectGroup("GatherMate", "RecipeProfit")
end

function RecipeProfit:UpdateButtons(event, ...)
    --print("UpdateButtons", event)
    if(WorldMapFrame:IsShown()) then
        local continent, zone = GetCurrentMapContinent(), GetCurrentMapZone()
        SetMapZoom(continent)
        SetMapZoom(continent, zone)
    else
        SetMapZoom(-1)
    end
    
    GatherMate:GetModule("Display"):UpdateMaps()
    
    if(not MerchantFrame:IsVisible()) then
        --print("UpdateButtons - (Event: ", event, ") - MerchantFrame not visible.");
        return;
    end
    
    for i=1, MERCHANT_ITEMS_PER_PAGE, 1 do
        local buttonframe = _G["MerchantItem"..i];
        local index = (((MerchantFrame.page - 1) * MERCHANT_ITEMS_PER_PAGE) + i);
        --print(index)
        if index <= GetMerchantNumItems() then
            button_update(buttonframe)
        end
    end
end   

function RecipeProfit:DoMerge()
    ids = {}
    local selectedDB = get_faction_db();
    
    GatherMate:ClearDB("RecipeProfit")
    for id, note in pairs(selectedDB) do
        x, y = find_good_id(note.x, note.y)
        add_note(x, y, note)
    end
    
    GatherMate:SendMessage("GatherMateDataImport")
    GatherMate:GetModule("Config"):SendMessage("GatherMateConfigChanged")
end

function get_note_title(note, factionTag)
    if(not factionTag) then
        _, factionTag = get_faction_db();
    end
    
    return note.item.." - ("..note.vendor.." ".. factionTag ..")";
end

function add_note(x, y, note)
    local coords = GatherMate:getID(x / 100, y / 100)
	local zoneID = GatherMate.zoneData[note.map][3]
    local nodeID = GatherMate.nodeIDs["RecipeProfit"][get_note_title(note, factionTag)]
    
    GatherMate:InjectNode(zoneID, coords, "RecipeProfit", nodeID);
end

function get_faction_db()
    local factionAlliance = db.profile.faction == "Alliance" or 
                            db.profile.faction == "default" and UnitFactionGroup("player") == "Alliance";
    if(factionAlliance) then
        return RECIPEPROFIT_alliance, "A";
    else
        return RECIPEPROFIT_horde,    "H";
    end
end

function safe_cache_vendor()
    if(not profile.enable_cache) then
        return
    end
    
    if(not profile.location_cache[UnitName("NPC")]) then
        SetMapToCurrentZone()
        local pos = {}
        pos.x, pos.y = GetPlayerMapPosition("player")
        profile.location_cache[UnitName("NPC")] = pos
    end
end

function button_update(self)
    local buttonName = _G[self:GetName().."Name"];
    local link = GetMerchantItemLink(_G[self:GetName().."ItemButton"]:GetID());
    if(not link) then
        return;
    end
    
    local sName, sLink, iRarity, iLevel, iMinLevel, sType, sSubType, iStackCount = GetItemInfo(link)
    
    if(sType == "Recipe" and safeRecipes[sName]) then 
        safe_cache_vendor();
        SetItemButtonNameFrameVertexColor(self, 0, 0, 1.0);
        SetItemButtonSlotVertexColor(self, 0, 0, 0.5);
        buttonName:SetText("* " .. sName)
        
        if(GetItemCount(link, true) == 0) then
            buttonName:SetTextColor(0,1,1);
        elseif(GetItemCount(link, true) < 5) then
            buttonName:SetTextColor(1,0,1);
        else
            buttonName:SetTextColor(1,0,0);
        end

    else
        buttonName:SetTextColor(GameFontNormalSmall:GetTextColor());
    end
end

function find_good_id(x, y)
    if ids[x.." "..y] then
        return find_good_id(x + .01, y)
    end
    
    ids[x.." "..y] = true
    return x, y
end   

local lastNodeTextureId = 0;

function get_next_texture_id()
    lastNodeTextureId = lastNodeTextureId + 1;
    return lastNodeTextureId;
end

function set_node_constants()
    GatherMate.nodeIDs["RecipeProfit"] = {}
    GatherMate.nodeTextures["RecipeProfit"] = {}
    GatherMate.nodeMinHarvest["RecipeProfit"] = {}
    
    local nodes = GatherMate.nodeIDs["RecipeProfit"]
    for id, note in pairs(RECIPEPROFIT_alliance) do
        safeRecipes[note.item] = true;
        local id = get_next_texture_id();
        nodes[get_note_title(note, "A")] = id;
        nodeLookup[id] = note;
    end
    
    for id, note in pairs(RECIPEPROFIT_horde) do
        safeRecipes[note.item] = true;
                local id = get_next_texture_id();
        nodes[get_note_title(note, "H")] = id;
        nodeLookup[id] = note;
    end
    
    for i = 1, lastNodeTextureId, 1 do
        GatherMate.nodeTextures["RecipeProfit"][i] = "Interface\\Icons\\INV_Scroll_05"
    end
    
    GatherMate.reverseNodeIDs["RecipeProfit"] = GatherMate:CreateReversedTable(nodes)
end

function inject_options()
    GatherMate:GetModule("Config").options.args.display.args.general.args.showGroup.args["showRecipeProfit"] = {
        order = 6,
        name = "Show RecipeProfit nodes.",
        desc = "Toggle showing nodes added by RecipeProfit.",
        type = "select",
        values = {
            ["always"] = "Always show",
            ["never"]  = "Never show",
        },
        arg = "RecipeProfit",
    }
    
    GatherMate:GetModule("Config").options.args.display.args.general.args.iconGroup.args.tracking.args["showRecipeProfit"] = {
        order = 6.5,
        name = "RecipeProfit",
        desc = "Color of the tracking circle.",
        type = "color",
        hasAlpha = true,
        arg = "RecipeProfit",		
    }
end

-- TODO: Fix
function get_colored_note_name(self, nodeID)
    local text = self.reverseNodeIDs["RecipeProfit"][nodeID]
    local sName, sLink, iRarity, iLevel, iMinLevel, sType, sSubType, iStackCount = GetItemInfo(nodeLookup[nodeID].itementry)
    
    if(not sLink) then
        return text
    end
    
    local count = GetItemCount(sLink, true)
    local prefix = "|cFF888888(" .. count .. ") |cFF66DD66"
    
    if(count == 0) then
        prefix = "|cFF00FFFF(" .. count .. ") |cFF66DD66"
    elseif(count >= 5) then
        prefix = "|cFFFF0000(" .. count .. ") |cFF66DD66"
    end
    
    return prefix .. text
end