view core.lua @ 44:d1b0e573a253

Added tag v2.01 for changeset c2a21288d680
author "Aaron Bregger <killermonkey99@gmail.com>"
date Tue, 04 Jan 2011 18:53:21 -0600
parents d97f61fad5b6
children 352fe939b884
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 this program.  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", "AceTimer-3.0")

local GatherMate = LibStub("AceAddon-3.0"):GetAddon("GatherMate2")

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 options = {
 	type = "group",
	name = "RecipeProfit", -- addon name to import from, don't localize
	handler = {},
	disabled = false,
	args = {
		heading = {
			order = 0,
			type = "description",
			name = "Thank you for using RecipeProfit for GatherMate!\n\n"..
                   "RecipeProfit was recently updated to work with patch 4.0.x and GatherMate 2. If you find any bugs you can report them on curse.com or curseforge.com by contacting the author 'Yuffles'. "..
                   "You can also email the author at killermonkey99".. --[[anti-spambot]] "@".."gmail.com (please try to put \"RecipeProfit\" in the subject!)\n\n"..
                   "You can toggle the display of RecipeProfit nodes on the map and minimap by changing the options in the general GatherMate 2 menu.",
			width = "full",
		},
    }
}

--maps wowhead IDs to localization independant map ids O_O
local zidmap={[1]=27,[3]=17,[4]=19,[8]=38,[10]=34,[11]=40,[12]=30,[14]=4,
    [15]=141,[16]=181,[17]=11,[28]=22,[33]=37,[38]=35,[40]=39,[41]=32,[44]=36,
    [45]=16,[46]=29,[47]=26,[51]=28,[65]=488,[66]=496,[67]=495,[85]=20,
    [130]=21,[139]=23,[141]=41,[148]=42,[210]=492,[215]=9,[267]=24,[331]=43,
    [357]=121,[361]=182,[394]=490,[400]=61,[405]=101,[406]=81,[440]=161,
    [490]=201,[493]=241,[495]=491,[616]=606,[618]=281,[1377]=261,[1497]=382,
    [1519]=301,[1537]=341,[1637]=321,[1638]=362,[1657]=381,[3430]=462,
    [3433]=463,[3483]=465,[3487]=480,[3518]=477,[3519]=478,[3520]=473,
    [3521]=467,[3522]=475,[3523]=479,[3524]=464,[3525]=476,[3537]=486,
    [3557]=471,[3703]=481,[3711]=493,[4080]=499,[4197]=501,[4395]=504,
    [4709]=607,[4714]=545,[4720]=544,[4737]=605,[4755]=611,[4815]=610,
    [4922]=700,[5034]=720,[5042]=640,[5095]=708,[5144]=615,[5145]=614,
    [5146]=613,[5287]=673,[5339]=689,[5416]=737,[5630]=737,[5695]=772
}

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("GatherMate2ConfigChanged")
    
    --[[ 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
        lself.db.profile.show["RecipeProfit"] = lself.db.profile.show["RecipeProfit"] == "never" and "never" or "always";
        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()
    InterfaceOptionsFrame_OpenToCategory("GatherMate 2")
    LibStub("AceConfigDialog-3.0"):SelectGroup("GatherMate 2", "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 alliance = get_faction_db();
    
    GatherMate:ClearDB("RecipeProfit")
    for id, note in pairs(RECIPEPROFIT_database) do
        if((note.a and alliance) or (note.h and not alliance)) then
            x, y = find_good_id(note.x, note.y)
            add_note(x, y, note)
        end
    end
    
    GatherMate:SendMessage("GatherMateDataImport")
    GatherMate:GetModule("Config"):SendMessage("GatherMate2ConfigChanged")
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.mapData:EncodeLoc(x/100, y/100, 0)
	local zoneID = zidmap[note.map]
    if(not zoneID) then
        return
    end
    
    local nodeID = GatherMate.nodeIDs["RecipeProfit"][get_note_title(note, "")]
    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 true, ""
    else
        return false, ""
    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_database) do
        safeRecipes[note.item] = true;
        local id = get_next_texture_id();

        nodes[get_note_title(note, "")] = 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()
    local acr = LibStub("AceConfigRegistry-3.0")
    acr:GetOptionsTable("GatherMate 2", "dialog", "RecipeProfit-1.0").args["showRecipeProfit"] = {
        order = 7,
        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"):SendMessage("GatherMate2ConfigChanged")
end

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
        RecipeProfit:ScheduleTimer("UpdateButtons", 3)
        return "|cFF000000(??) |cFF66DD66" .. text .. "|cFFFF0000 Please Wait (Querying Server)..."
    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