vanilla-wow-addons – Rev 1
?pathlinks?
-- SoulStamp
SOULSTAMP_VERSION="0.1";
-- This addon tracks the source of soul shards (the mob or player they were created from)
-- and adds this information under a tooltip you can see when mousing over the shard.
-- This information is at the moment only visible to you.
--
-- Much of the infrastructure code for detecting spell casts
-- was shamelessly stolen from CountDoom.
--
-- Copyright (c) 2006 Colin Walters <cgwalters@gmail.com>
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
--
-- * Redistributions of source code must retain the above copyright notice, this list
-- of conditions and the following disclaimer.
-- * Redistributions in binary form must reproduce the above copyright notice, this list
-- of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-- * The names of its contributors may not be used to endorse
-- or promote products derived from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-- IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
SoulStamp = {};
SoulStamp.debug = false;
SoulStamp.initialized = false;
-- Utility functions stolen from CountDoom
SoulStamp.Chat = function(msg, r, g, b)
local msgOutput = DEFAULT_CHAT_FRAME;
if(msgOutput) then
msgOutput:AddMessage(msg, r, g, b);
end
end;
SoulStamp.Debug = function(msg, r, g, b)
if (SoulStamp.debug) then
SoulStamp.Chat("<SSDebug>: " .. msg, r, g, b);
end
end;
SoulStamp.ToString = function(arg1)
local argType = type(arg1);
if argType == "nil" then
return "nil";
elseif argType == "boolean" then
if arg1 then
return "true";
else
return "false";
end
else
return "" .. arg1;
end
end;
-- Stolen from auctioneer
SoulStamp.BreakLink = function(link)
local i,j, itemID, enchant, randomProp, uniqID, name = string.find(link, "|Hitem:(%d+):(%d+):(%d+):(%d+)|h[[]([^]]+)[]]|h");
return tonumber(itemID or 0), tonumber(randomProp or 0), tonumber(enchant or 0), tonumber(uniqID or 0), name;
end
SoulStamp.BreakItemKey = function(itemKey)
local i,j, itemID, randomProp, enchant = string.find(itemKey, "(%d+):(%d+):(%d+)");
return tonumber(itemID or 0), tonumber(randomProp or 0), tonumber(enchant or 0);
end
SoulStamp.lastSpellTarget = nil;
SoulStamp.drainSoulActive = false;
SoulStampShardSourceMap = {};
SoulStamp.shardSourceMap = SoulStampShardSourceMap;
local initSoulStampShardSourceMap = SoulStampShardSourceMap;
function SSFrame_OnLoad()
this:RegisterEvent("ADDON_LOADED");
this:RegisterEvent("VARIABLES_LOADED");
this:RegisterEvent("SPELLCAST_STOP");
this:RegisterEvent("SPELLCAST_FAILED");
this:RegisterEvent("SPELLCAST_INTERRUPTED");
this:RegisterEvent("ITEM_PUSH");
this:RegisterEvent("CHAT_MSG_LOOT");
this:RegisterEvent("BAG_UPDATE");
end;
function SSFrame_OnEvent(event)
if (event == "VARIABLES_LOADED") then
SoulStamp.Initialize();
elseif event == "SPELLCAST_INTERRUPTED" or event == "SPELLCAST_FAILED" then
SoulStamp.SpellCastFailedCallback()
-- User stopped casting a spell
elseif event == "SPELLCAST_STOP" then
SoulStamp.SpellCastStoppedCallback()
elseif event == "ITEM_PUSH" then
SoulStamp.ItemPushCallback(arg1, arg2)
elseif event == "CHAT_MSG_LOOT" then
SoulStamp.LootCallback(arg1)
elseif event == "BAG_UPDATE" then
SoulStamp.BagUpdateCallback(arg1)
elseif event == "ADDON_LOADED" and arg1 == "SoulStamp" then
SoulStamp.shardSourceMap = SoulStampShardSourceMap;
end;
end;
SoulStamp.IsItemSoulShard = function(name)
return string.find(name, "Soul Shard");
end;
SoulStamp.ForeachSoulShardInBag = function(func, bag)
for slot=1,GetContainerNumSlots(bag) do
local link = GetContainerItemLink(bag,slot);
if (link) then
local itemID, randomProp, enchant, uniqID, lame = SoulStamp.BreakLink(link);
if (SoulStamp.IsItemSoulShard(lame)) then
SoulStamp.Debug("Soul shard at slot=" .. SoulStamp.ToString(slot) .. " uniqId=" .. SoulStamp.ToString(uniqId));
func(uniqID, lame);
end
end
end
end;
SoulStamp.ForeachSoulShard = function(func, bag)
local bag;
for bag=0,4 do
SoulStamp.ForeachSoulShardInBag(func, bag);
end;
end;
SoulStamp.Initialize = function()
SLASH_SOULSTAMP1 = "/soulstamp";
SlashCmdList["SOULSTAMP"] = function(msg)
SoulStamp.SlashCommand(msg);
end
SoulStamp.Debug("SoulStamp " .. SOULSTAMP_VERSION .. " by Xalan of Crushridge initalized");
-- Hook into the tooltip popup functions
SoulStamp.OrigContainerFrameItemButton_OnEnter = ContainerFrameItemButton_OnEnter;
ContainerFrameItemButton_OnEnter = SoulStamp.ContainerFrameItemButton_OnEnter;
SoulStamp.DumpShards();
end;
SoulStamp.SlashCommand = function(msg)
msg = string.lower(msg);
local a, b, c, n = string.find (msg, "(%w+) ([_%w]+)");
if( c == nil and n == nil ) then
a, b, c = string.find (msg, "(%w+)");
end
if (c ~= nil) then
SoulStamp.Debug("c:"..c);
else
SoulStamp.Debug("c: nil");
end
if (n ~= nil) then
SoulStamp.Debug("n:"..n);
else
SoulStamp.Debug("n: nil");
end
if(c == "debug") then
SoulStamp.debug = not SoulStamp.debug;
if (SoulStamp.debug) then
SoulStamp.Chat("SoulStamp debug is now on");
else
SoulStamp.Chat("SoulStamp debug is now off");
end
elseif (c == "dumpshards") then
SoulStamp.DumpShards();
elseif (c == "dumpmap") then
SoulStamp.DumpShardMap();
end
end
SoulStamp.DumpShards = function()
local function ssCallback(uniqID, lame)
SoulStamp.Chat("shard=" .. uniqID);
end;
SoulStamp.ForeachSoulShard(ssCallback);
end;
SoulStamp.DumpShardMap = function()
for k,v in pairs(SoulStamp.shardSourceMap) do
SoulStamp.Chat("shard=" .. SoulStamp.ToString(k) .. " maps to " .. SoulStamp.ToString(v));
end;
end;
SoulStamp.SpellCastStartCallback = function (spellName, spellRank)
SoulStamp.Debug("Cast of: " .. SoulStamp.ToString(spellName) .. " Rank: " .. SoulStamp.ToString(spellRank));
SoulStamp.lastSpellTarget = UnitName("target");
end;
SoulStamp.SpellCastFailedCallback = function ()
SoulStamp.Debug("Last spell cast failed");
end;
SoulStamp.SpellCastStoppedCallback = function ()
SoulStamp.Debug("Last spell cast stopped");
end;
SoulStamp.ItemPushCallback = function (stackSize, iconPath)
SoulStamp.Debug("Item push: " .. SoulStamp.ToString(stackSize) .. " " .. SoulStamp.ToString(iconPath));
end;
SoulStamp.OnSoulShardCreated = function()
SoulStamp.Debug("Soul shard created from " .. SoulStamp.ToString(SoulStamp.lastSpellTarget));
if (not SoulStamp.lastSpellTarget) then
SoulStamp.Debug("ERROR: no previous spell target after creating soul shard")
return;
end;
local foundUnknownShard = false;
local function ssCallback(uniqID, lame)
if (foundUnknownShard) then
return;
end;
if (not SoulStamp.shardSourceMap[uniqID]) then
SoulStamp.Debug("assigning shard " .. uniqID .. " to " .. SoulStamp.lastSpellTarget);
SoulStamp.shardSourceMap[uniqID] = SoulStamp.lastSpellTarget;
foundUnknownShard = true;
end;
end;
SoulStamp.ForeachSoulShard(ssCallback);
end;
SoulStamp.LootCallback = function(msg)
SoulStamp.Debug("Loot: " .. SoulStamp.ToString(msg));
if (string.find(msg, "You create.+Soul Shard")) then
SoulStamp.OnSoulShardCreated();
end
end;
SoulStamp.BagUpdateCallback = function(bag)
SoulStamp.Debug("Bag update: " .. SoulStamp.ToString(bag));
end;
SoulStamp.ContainerFrameItemButton_OnEnter = function ()
SoulStamp.OrigContainerFrameItemButton_OnEnter();
local frameID = this:GetParent():GetID();
local frame = GameTooltip;
local buttonID = this:GetID();
local link = GetContainerItemLink(frameID, buttonID);
-- SoulStamp.Debug("ContainerFrameItemButton_OnEnter frameId=" .. SoulStamp.ToString(frameID) .. " buttonID=" .. SoulStamp.ToString(buttonID) .. " link=" .. SoulStamp.ToString(link));
if (not link) then
return;
end;
local itemID, randomProp, enchant, uniqID, lame = SoulStamp.BreakLink(link);
local itemKey = itemID..":"..randomProp..":"..enchant;
-- SoulStamp.Debug("ContainerFrameItemButton_OnEnter lame=" .. SoulStamp.ToString(lame) .. "uniqID=" .. SoulStamp.ToString(uniqID));
if (not string.find(lame, "Soul Shard")) then
return;
end;
local source = SoulStamp.shardSourceMap[uniqID];
if (not source) then
frame:AddLine("Source unknown", 0.6, 0.6, 0.6);
else
frame:AddLine("Drained from " .. source .. "", 0.7, 0, 0);
end;
frame:Show();
end
-- Hook into CastSpell
SoulStamp.oldCastSpell = CastSpell;
SoulStamp.OnCastSpell = function (spellId,spellbookTabNum)
local spellName, spellRank = GetSpellName(spellId, spellbookTabNum);
if spellRank ~= nil then
local _, _, spellRankString = string.find(spellRank, "(%d+)");
rank = tonumber(spellRankString);
end;
SoulStamp.SpellCastStartCallback(spellName, rank);
SoulStamp.oldCastSpell(spellId, spellbookTabNum);
end;
CastSpell = SoulStamp.OnCastSpell;
SoulStamp.oldCastSpellByName = CastSpellByName;
SoulStamp.OnCastSpellByName = function(spellString)
local startIndex, endIndex, spellName = string.find(spellString, "(.+)%(");
local _, _, spellRankStr = string.find(spellString, "([%d]+)");
local rank = nil;
rank = tonumber(spellRankStr);
SoulStamp.SpellCastStartCallback(spellName, rank);
SoulStamp.oldCastSpellByName(spellString);
end;
CastSpellByName = SoulStamp.OnCastSpellByName;
SoulStamp.oldUseAction = UseAction;
SoulStamp.OnUseAction = function (a1, a2, a3)
SoulStamp.Debug("Got OnUseAction: " .. SoulStamp.ToString(a1));
-- Only process if it isn't a macro
if GetActionText(a1) == nil then
-- This screwy code is stolen from CountDoom
SS_SpellDetector:Hide();
SS_SpellDetector:SetOwner(SoulStampFrame,"ANCHOR_NONE");
SS_SpellDetector:SetAction(a1);
local spellName = nil;
if SS_SpellDetectorTextLeft1 ~= nil then
spellName = SS_SpellDetectorTextLeft1:GetText();
end;
local spellRank = nil;
if SS_SpellDetectorTextRight1 ~= nil then
spellRank = SS_SpellDetectorTextRight1:GetText();
end;
local rank = nil;
if spellRank ~= nil then
local _, _, spellRankString = string.find( spellRank, "[^%d]*(%d+)");
rank = tonumber(spellRankString);
end;
SoulStamp.SpellCastStartCallback(spellName, rank);
end
SoulStamp.oldUseAction(a1, a2, a3);
end;
UseAction = SoulStamp.OnUseAction;