vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--[[
GuildTools v 2.4

Addon that allows you to store in game info into SV.lua for further parsing.
Contains: 
BankScan     - scans all posessions of the character, including bank, bags amd bags in bank.
IncomingMail - grabs all the nonCOD items and money from mailbox as soon as it's opened. 
               Also keeps track of all the incoming mail including sender, item sent, money sent
                           and date when the message was received.
                           
Author: Roman Tarakanov (RTE/Arthas)
Date: Mar 28 '06

]]--
---------------------------------------------------------------
----------------------Standart mesages-------------------------
---------------------------------------------------------------

local GT_VER    = "2.4";
local GT_BS_VER = "2.3";
local GT_IM_VER = "2.3";

local MSG_GT_GREETING1 = "GuildTools v" .. GT_VER .. " is loaded.";
local MSG_GT_GREETING2 = "For more information type /gts info.";
local MSG_GT_GREETING = "GuildTools v" .. GT_VER .. ".";
local MSG_BS_GREETING = "BankScan v" .. GT_BS_VER .. ".";
local MSG_IM_GREETING = "IncomingMail v" .. GT_IM_VER .. ".";

local MSG_GT_ADDONOFF = "GT> AddOn is turned off, use /gts on to turn it on for this character";
local MSG_GT_ON = "GT> AddOn is now ENABLED for this character";
local MSG_GT_OFF = "GT> AddOn is now DISABLED for this character";
local MSG_GT_CLEARED = "GT> Variables have been cleared.";
local MSG_GT_INVALID = "GT> Not a valid command. See /gts info for list of commands.";
local MSG_DEBUG_ON = "GT> Debug mode is now ENABLED for this character";
local MSG_DEBUG_OFF = "GT> Debug mode is now DISABLED for this character";

local MSG_BS_ON = "GT> BankScan part of this AddOn is now ENABLED for this character";
local MSG_BS_OFF = "GT> BankScan part of this AddOn is now DISABLED for this character";
local MSG_BS_SORTON = "GT> BankScan's sort function is ENABLED";
local MSG_BS_SORTOFF = "GT> BankScan's sort function is DISABED";
local MSG_BS_OK = "GT> BankScan | Success : prescan was successful, now you can run finalize to save the data";
local MSG_BS_DONE = "GT> BankScan | Success : finilize was successful, now you can log out and run BankParser.exe to get html file";
local MSG_BS_BANKCLOSED = "GT> BankScan | Error : bank must be opened for this script to work.";

local MSG_IM_ON = "GT> IncomingMail part of this AddOn is now ENABLED for this character";
local MSG_IM_OFF = "GT> IncomingMail part of this AddOn is now DISABLED for this character";
local MSG_IM_START = "GT> IncomingMail started taking mail. Please do not do anything.";
local MSG_IM_CANCELED = "GT> IncomingMail grabbing procedure was canceled, some of the data might be corupted.";
local MSG_IM_SUCCESS = "GT> IncomingMail successfully grabbed your mail.";
local MSG_IM_SAVED = "GT> Mailed items database have been saved in SV. You can now run MailParser to get html file.";
local MSG_IM_CLEARED = "GT> IncomingMail varibles are cleared.";
local MSG_IM_NOBAG = "GT> There are no empy slots in your bags. Canceling IncomingMail.";

---------------------------------------------------------------
----------------Global GuildTools variables--------------------
---------------------------------------------------------------

--BankOpen indicator
-- 0 - bank closed
-- 1 - bank opened
local BankStatus = 0;
--Position in the array GT_Saved of the current character 
-- -1 - not in array
local Position=-1;
--Debug mode indicator 
-- 1 - debug mode on
-- 0 - debug mode off (default)
local DebugMode = 0;

---------------------------------------------------------------
------------------Global BankScan variables--------------------
---------------------------------------------------------------

--List of the bags to look in
local BanknBags = { -1, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4};
local MoneyScanned = 1;

---------------------------------------------------------------
---------------Global IncomingMail variables-------------------
---------------------------------------------------------------

local MailOpened = false;
local State = 0;

local availableSlots = {};
local numSlots = 0;
local emptySlots = 0;
local currentMessage = 1;
local From = 0;
local To = 0;

---------------------------------------------------------------
----------------Global GuildTools functions--------------------
---------------------------------------------------------------
function GT_Bsclear()
                if (GT_Saved[Position].addonOn) then
                        --GT_Saved = {};
                        GT_BS_ScannedItems = {};
                        GT_BS_PreScannedItems = {};
                        GT_BS_Money = 0;
                        GT_IM_Saved = {};
                        GT_IM_MailedItems[Position] = {};
                        GT_IM_NumMailedItems[Position] = 0;
                        GT_Echo(MSG_GT_CLEARED);
                else
                        GT_Echo(MSG_ADDONOFF);
                end
end

function GT_On()
        GT_Saved[Position].addonOn = true;
        GT_Echo(MSG_GT_ON);
end

function GT_Bson()
        GT_Saved[Position].BSOn = true;         
        GT_Echo(MSG_BS_ON);
end

function GT_Bscan()
                if (GT_Saved[Position].BSOn) then
                        NumItems = 1;
                        if (BankStatus == 1) then
                                GT_BS_PreScannedItems = {};
                                GT_Debug("GT_BS_DoScan is called.");
                                GT_BS_DoScan();
                                GT_Debug("GT_BS_DoScan exited.");
                                GT_BS_Money = " "..GetMoney().." ";
                                GT_BS_Finalize();
                                GT_Echo(MSG_BS_DONE);
                        else
                                GT_Echo(MSG_BS_BANKCLOSED);
                        end
                else
                        GT_Echo(MSG_ADDONOFF);
                end
end

function GT_RegisterUltimateUI()
        UltimateUI_RegisterConfiguration(
                "UUI_GT",
                "SECTION",
                "Guild Tools",
                "Shortcuts to use Guild Tools."
        );
        UltimateUI_RegisterConfiguration(
                "UUI_GT_SEPARATOR",
                "SEPARATOR",
                "Guild Tools",
                "Shortcuts to use Guild Tools."
        );
        UltimateUI_RegisterConfiguration(
                "UUI_GT_CLEAR",
                "BUTTON",
                "",
                "",
                GT_Bsclear,
                0,
                0,
                0,
                0,
                "/gts bsclear"
        );
        UltimateUI_RegisterConfiguration(
                "UUI_GT_CLEAR",
                "BUTTON",
                "",
                "",
                GT_On,
                0,
                0,
                0,
                0,
                "/gts on"
        );
        UltimateUI_RegisterConfiguration(
                "UUI_GT_CLEAR",
                "BUTTON",
                "",
                "",
                GT_Bson,
                0,
                0,
                0,
                0,
                "/gts bson"
        );
        UltimateUI_RegisterConfiguration(
                "UUI_GTT_SEPARATOR",
                "SEPARATOR",
                "Scan!",
                "Scan button below!"
        );
        UltimateUI_RegisterConfiguration(
                "UUI_GT_CLEAR",
                "BUTTON",
                "",
                "",
                GT_Bscan,
                0,
                0,
                0,
                0,
                "/gts bscan"
        );
end


--OnEvent function
function GT_OnEvent()    
        GT_Debug("OnEvent is called");

        if (event == "VARIABLES_LOADED") then
                GT_Debug("Variables are loaded.");
                GT_RegisterUltimateUI();
                SlashCmdList["GUILDTOOLS"] = GT_SlashCommand;
                SLASH_GUILDTOOLS1 = "/guildtools";
                SLASH_GUILDTOOLS2 = "/gts";
                
                --GT_Saved = {};
                --GT_BS_ScannedItems = {};
                --GT_IM_MailedItems = {};
                --GT_IM_NumMailedItems = {};
                
                --Saved variables of the AddOn
                --Initialize if blank           
                if (not GT_Saved) then
            GT_Saved = {};
                end
                
                --Find varibles in GT_Saved if exist
                local i;
                GT_Debug("GT_Saved size: "..table.getn(GT_Saved));
                if (GT_Saved) then
                        for  i = 1, table.getn(GT_Saved), 1 do
                                if (string.find(GT_Saved[i].name, UnitName("player")) and string.find(GT_Saved[i].server, GetCVar("realmName"))) then
                                        if (not GT_Saved[i].addonOn) then GT_Saved[i].addonOn=false; end
                                        if (not GT_Saved[i].BSOn) then GT_Saved[i].BSOn=false; end
                                        if (not GT_Saved[i].mailOn) then GT_Saved[i].mailOn=false; end
                                        Position = i;
                                end
                        end
                end
                
                --If new character is observed - initialize the data.
                --On new character AddOn and mail grabber part (future functionality) are off by default
                if (Position == -1) then
                        if (GT_Saved) then
                                i = table.getn(GT_Saved)+1;
                        else
                                i = 1;
                        end             
                        GT_Saved[i] = { name=UnitName("player"), server=GetCVar("realmName"), 
                                mailOn=false, addonOn=false, BSOn=false, BSSort=1};
                        Position = i;
                end
                
                GT_Debug("Position: "..Position);
                GT_Echo(MSG_GT_GREETING1);
                GT_Echo(MSG_GT_GREETING2);
                
                if (not GT_IM_Saved) then GT_IM_Saved = {}; end
                if (not GT_IM_NumMailedItems) then GT_IM_NumMailedItems = {}; end
                if (not GT_IM_MailedItems) then GT_IM_MailedItems = {}; end
                if (not GT_IM_NumMailedItems[Position]) then GT_IM_NumMailedItems[Position] = 0; end
                if (not GT_IM_MailedItems[Position]) then GT_IM_MailedItems[Position] = {}; end
                if (not GT_BS_PreScannedItems) then GT_BS_PreScannedItems = {}; end
                if (not GT_BS_Money) then GT_BS_Money = 0; MoneyScanned = nil; end
                
        elseif (event == "BANKFRAME_OPENED") then
                GT_Debug("Bank was opened.");
                BankStatus = 1;

        elseif (event == "BANKFRAME_CLOSED") then
                GT_Debug("Bank was closed.");           
                BankStatus = 0;
        
        elseif (not GT_Saved[Position].addonOn) then return; 
        
        elseif (event == "MAIL_SHOW") then
                if (GT_Saved[Position].mailOn) then
                        MailOpened = true;
                        State = 0;
                        GT_Echo(MSG_IM_START);
                        GT_IM_ScanSlots();
                end
                
        elseif (event == "MAIL_CLOSED") then
                if (GT_Saved[Position].mailOn) then
                        GT_Debug("State = "..State);
                        if (State < 11 and State ~= -99) then GT_Echo(MSG_IM_CANCELED); end
                        MailOpened = false;
                        State = -99;
                        GT_IM_Message:Hide();
                        GT_IM_Update:Hide();
                end
                
        elseif (event == "MAIL_INBOX_UPDATE") then
                if (GT_Saved[Position].mailOn) then
                        GT_Debug("grab!!!!!");
                        GT_IM_Update:Show();
                end
                
        elseif (event == "BAG_UPDATE") then
                if (GT_Saved[Position].addonOn and GT_Saved[Position].mailOn) then
                        GT_IM_ScanItems();
                end             
        end
end

--Slash command handler
function GT_SlashCommand(msg)
        msg = string.lower(msg);
        GT_Debug("/command: "..msg);

---------------------------------------------------------------
------------------GT standart commands-------------------------
---------------------------------------------------------------
        if (msg == "on") then
                GT_Saved[Position].addonOn = true;
                GT_Echo(MSG_GT_ON);
                
        elseif (msg == "off") then
                GT_Saved[Position].addonOn = false;
                GT_Echo(MSG_GT_OFF);
                
        elseif (msg == "debug") then
                
                if (DebugMode == 1) then
                        GT_Echo(MSG_DEBUG_OFF);
                        DebugMode = 0;
                else
                        GT_Echo(MSG_DEBUG_ON);
                        DebugMode = 1;
                end
                
        elseif (msg == "status") then
                if (GT_Saved[Position].addonOn) then
                        
                        local status = "DISABLED";
                        if (GT_Saved[Position].addonOn) then 
                                status = "ENABLED";
                        end
                        GT_Echo("GT> AddOn  is "..status..", see /gts info for information on the AddOn.");
                        
                        status = "DISABLED";
                        if (GT_Saved[Position].BSOn) then 
                                status = "ENABLED";
                        end
                        GT_Echo("GT> BankScan is "..status..", see /gts bsinfo for list of commands.");
                        
                        status = "DISABLED";
                        if (GT_Saved[Position].mailOn) then 
                                status = "ENABLED";
                        end
                        GT_Echo("GT> MailGrabber is "..status..", see /gts iminfo for list of commands.");
                        
                        status = "DISABLED";
                        if (DebugMode == 1) then 
                                status = "ENABLED";
                        end
                        GT_Echo("GT> Debug mode is "..status..".");
                        
                else
                        GT_Echo(MSG_ADDONOFF);
                end
                
        elseif (msg == "info") then
                GT_Echo(MSG_GT_GREETING);
                GT_Echo("GT> Scans possesions of the char, including bank into SV.lua.");
                GT_Echo("GT> List of components:");
                GT_Echo("GT> BankScan - scanns possesions of char. See /gts bsinfo for more info.");
                GT_Echo("GT> IncomingMail - tracks incoming mail. See /gts iminfo for more info.");
                GT_Echo("GT> -------------------------------------------------------------------");
                GT_Echo("GT> Available commands:");
                GT_Echo("GT> /gts status   shows the status of GuildTools and components.");
                GT_Echo("GT> /gts <on/off> turns the GuildTools on/off for this char.");
                GT_Echo("GT> /gts clear    clears all saved variables for this addon. If used all data will be lost.");
                GT_Echo("GT> /gts debug    tuggles Debug Mode on/off.");
                GT_Echo("GT> /gts info     shows this screen.");
                
        elseif (not GT_Saved[Position].addonOn) then
                GT_Echo(MSG_GT_ADDONOFF);
                return;
                
        elseif (msg == "clear") then
                if (GT_Saved[Position].addonOn) then
                        --GT_Saved = {};
                        GT_BS_ScannedItems = {};
                        GT_BS_PreScannedItems = {};
                        GT_BS_Money = 0;
                        GT_IM_Saved = {};
                        GT_IM_MailedItems[Position] = {};
                        GT_IM_NumMailedItems[Position] = 0;
                        GT_Echo(MSG_GT_CLEARED);
                else
                        GT_Echo(MSG_ADDONOFF);
                end
                
        elseif (msg == "vars") then
                if (MailOpened) then 
                        GT_Debug("MailOpened: true"); 
                else 
                        GT_Debug("MailOpened: false"); 
                end
                GT_Debug("State: "..State);
                GT_Debug("From = "..From..", To = "..To);
                
---------------------------------------------------------------
-------------------------BS commands---------------------------
---------------------------------------------------------------
        elseif (msg == "bs") then
                local status = "DISABLED";
                if (GT_Saved[Position].BSOn) then 
                        status = "ENABLED";
                end
                GT_Echo(MSG_BS_GREETING1);
                GT_Echo("GT> BankScan BankScan is "..status..", see /gts bsinfo for list of commands.");
                
        elseif (msg == "bson") then
                GT_Saved[Position].BSOn = true;         
                GT_Echo(MSG_BS_ON);
                
        elseif (msg == "bsoff") then
                GT_Saved[Position].BSOn = false;
                GT_Echo(MSG_BS_OFF);
                
        elseif (msg == "bssort") then
                if (GT_Saved[Position].BSSort==1) then
                        GT_Saved[Position].BSSort=2;            
                        GT_Echo(MSG_BS_SORTOFF);
                else
                        GT_Saved[Position].BSSort=1;            
                        GT_Echo(MSG_BS_SORTON);
                end
                
        elseif (msg == "bscan") then
                if (GT_Saved[Position].BSOn) then
                        NumItems = 1;
                        if (BankStatus == 1) then
                                GT_BS_PreScannedItems = {};
                                GT_Debug("GT_BS_DoScan is called.");
                                GT_BS_DoScan();
                                GT_Debug("GT_BS_DoScan exited.");
                                GT_BS_Money = " "..GetMoney().." ";
                                GT_BS_Finalize();
                                GT_Echo(MSG_BS_DONE);
                        else
                                GT_Echo(MSG_BS_BANKCLOSED);
                        end
                else
                        GT_Echo(MSG_ADDONOFF);
                end
                
        elseif (msg == "bsprescan") then
                if (GT_Saved[Position].BSOn) then
                        NumItems = 1;
                        if (BankStatus == 1) then
                                if (not MoneyScanned) then GT_Debug("Clear money"); GT_BS_Money = 0; end
                                GT_BS_Money = GT_BS_Money+GetMoney();
                                MoneyScanned = 1;
                                GT_Debug("GT_BS_DoScan is called.");
                                GT_BS_DoScan();
                                GT_Debug("GT_BS_DoScan exited.");
                                GT_Echo(MSG_BS_OK);
                        else
                                GT_Echo(MSG_BS_BANKCLOSED);
                        end
                else
                        GT_Echo(MSG_ADDONOFF);
                end     
                
        elseif (msg == "bsfinal") then
                if (GT_Saved[Position].BSOn) then
                        GT_BS_Money = " "..GT_BS_Money.." ";
                        GT_BS_Finalize();
                        GT_Echo(MSG_BS_DONE);
                else
                        GT_Echo(MSG_ADDONOFF);
                end
                
        elseif (msg == "bsinfo") then
                GT_Echo(MSG_BS_GREETING);
                GT_Echo("GT> Scans possesions of the char, including bank into SV.lua.");
                GT_Echo("GT> Available commands:");
                GT_Echo("GT> /gts bs         shows the status of BankScan.");
                GT_Echo("GT> /gts bs<on/off> turns the BankScan on/off for this char.");
                GT_Echo("GT> /gts sort       tuggles the BankScan's sorting function on/off for this char.");
                GT_Echo("GT> /gts bscan      performs the scan of possesions of this char for parsing into SV.lua.");
                GT_Echo("GT> /gts bsprescan  performs the scan of possesions of this char and adds them to priviously scanned.");
                GT_Echo("GT> /gts bsfinal    sends all the scanned data from bsprescan for parsing into SV.lua.");
                GT_Echo("GT> /gts bsinfo     shows this screen.");
                
---------------------------------------------------------------
-------------------------IM commands---------------------------
---------------------------------------------------------------
        elseif (msg == "im") then
                local status = "DISABLED";
                if (GT_Saved[Position].addonOn) then 
                        status = "ENABLED";
                end
                GT_Echo("GT> IncomingMail is "..status..", see /gts iminfo for list of commands.");
                
        elseif (msg == "imon") then
                GT_Saved[Position].mailOn = true;       
                GT_Echo(MSG_IM_ON);
                
        elseif (msg == "imoff") then
                GT_Saved[Position].mailOn = false;
                GT_Echo(MSG_IM_OFF);
                
        elseif (msg == "imsave") then
                GT_IM_Save();
                GT_Echo(MSG_IM_SAVED);
                
        elseif (msg == "imclear") then
                if (GT_Saved[Position].mailOn) then
                        GT_IM_MailedItems[Position] = {};
                        GT_IM_NumMailedItems[Position] = 0;             
                        GT_Echo(MSG_IM_CLEARED);
                else
                        GT_Echo(MSG_IMOFF);
                end
                
        elseif (msg == "iminfo") then
                GT_Echo(MSG_IM_GREETING1);
                GT_Echo("GT> Grabs all the nonCoD mail from your mailbox.");
                GT_Echo("GT> Also stores info about all the incoming mail in database.");
                GT_Echo("GT> Available commands:");
                GT_Echo("GT> /gts im         shows the status of IncomingMail.");
                GT_Echo("GT> /gts im<on/off> turns the IncomingMail on/off for this char.");
                GT_Echo("GT> /gts imsave     saves database of this char for parsing in SV.lua.");
                GT_Echo("GT> /gts imclear    clears database for this character (Saved with /gm imsave stays intact).");
                GT_Echo("GT> /gts iminfo     shows this screen.");
                
---------------------------------------------------------------
----------------------End of  commands-------------------------
---------------------------------------------------------------
        else
                GT_Echo(MSG_GT_INVALID);
                
        end
end

--Returns full info of the item on bag_id, slot_id, nil if item is not there
function GT_GetItemInfo(bag_id, slot_id)
        local count, texture, itemLink, itemName, i, command, itemQuality, itemDesc, itemType, itemSubType, itemId;
        
        if (not GetContainerItemInfo(bag_id, slot_id)) then 
                GT_Debug("No item in the slot "..bag_id..", "..slot_id);
                return nil;
        end
        
        --Get texture and count of the item in the current slot
        texture, count = GetContainerItemInfo(bag_id, slot_id);
        _,_,texture = string.find(texture, "%a+\\%a+\\([%w_]+)");
        
        --Get link and the name of the item in the current slot
        itemLink = GetContainerItemLink(bag_id, slot_id);
        _, _, itemLink, itemName = string.find(itemLink,
        "|H(item:%d+:%d+:%d+:%d+)|h%[([^]]+)%]|h|r$");
        _, _, itemQuality, _, itemType, itemSubType = GetItemInfo(itemLink);
        
        GT_Debug("Link: "..itemLink);
        --Set tooltip to the current item
        GT_ItemTooltip:SetOwner(this,"ANCHOR_BOTTOMRIGHT");
        GT_ItemTooltip:ClearLines();
        GT_ItemTooltip:SetHyperlink(itemLink);
        
        --Copy the description test from the tooltip to the variable
        --<n> - new line symbol
        --<t> - tab symbol
        for i=1, GT_ItemTooltip:NumLines(),1 do
        
                command = getglobal("GT_ItemTooltipTextLeft" .. i);
                if (command:IsShown()) then
                        text_left = command:GetText();
                else
                        text_left = nil;
                end
                
                command = getglobal("GT_ItemTooltipTextRight" .. i);
                if (command:IsShown()) then
                        text_right = command:GetText();
                else
                        text_right = nil;
                end
                
                if (text_left and string.find(text_left, "\n")) then
                        text_left = " ";
                end
                
                if (text_right and string.find(text_right, "\n")) then
                        text_right = " ";
                end
                
                if (i == 1) then 
                        itemDesc = text_left;
                else
                        if (text_left) then 
                                itemDesc = itemDesc.." <n> "..text_left;
                        end
                end
                if (text_right) then
                  itemDesc = itemDesc.." <t> "..text_right;
                end
        end
        _,_,itemId = string.find(itemLink,"item:(%d+):%d+:%d+:%d+");
        GT_Debug("ID: "..itemId);
        return itemName, itemQuality, itemDesc, count, texture, itemType, itemSubType, itemId;
end

--Prints message into the text chat window
function GT_Echo(message)
        if ( DEFAULT_CHAT_FRAME ) then 
                DEFAULT_CHAT_FRAME:AddMessage(message, 0.5, 0.5, 1.0);
        end
end

--Prints debug message into the chat window iff local variable DebugMode is set to 1
--otherwise does nothing
function GT_Debug(message)
        if (DebugMode == 1) then
                message = "GT><**Debug**> " .. message;
                if ( DEFAULT_CHAT_FRAME ) then 
                        DEFAULT_CHAT_FRAME:AddMessage(message, 1.0, 0.0, 0.0);
                end
        end
end

---------------------------------------------------------------
---------------------BankScan functions------------------------
---------------------------------------------------------------

--This function actually scans all bags for items
function GT_BS_DoScan()
        --Array of items that will be saved in SavedVariables.lua
        --Initiated as empty, if BankScan is not called during the session all data will be wiped upon logout
        GT_BS_ScannedItems = {};

        local index, bag_id, slot_id, count, texture, itemLink, itemName, i, command, itemQuality, itemDesc, itemType, itemSubType, itemId;

        --Go through every slot in the bags (and bank)
        for index, bag_id in BanknBags do
                if (GetContainerNumSlots(bag_id)) then
                        for slot_id = 1, GetContainerNumSlots(bag_id), 1 do
                                if (GetContainerItemLink(bag_id, slot_id)) then
                                        
                                        itemName, itemQuality, itemDesc, count, texture, itemType, itemSubType, itemId = GT_GetItemInfo(bag_id, slot_id);
                                        
                                        --Save info on current item in the array
                                        if (not GT_BS_PreScannedItems[itemName]) then
                                                GT_BS_PreScannedItems[itemName] = {description="  "..itemDesc.." ",
                                                                                                                number=count,
                                                                                                                pic=" "..texture.." ", 
                                                                                                                quality=itemQuality,
                                                                                                                subtype = " "..itemSubType.." ",
                                                                                                                type = " "..itemType.." ",
                                                                                                                id = " "..itemId.." "};
                                                --Sorting function
                                                if (GT_Saved[Position].BSSort == 1) then
                                                        if(itemType=="Trade Goods") then 
                                                                GT_BS_PreScannedItems[itemName].sort = 900;
                                                                if (itemSubType=="Devices") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 36 - 300;
                                                                elseif (itemSubType=="Explosives") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 35 - 300;
                                                                elseif (itemSubType=="Parts") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 58;
                                                                elseif (itemSubType=="Trade Goods") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 59;
                                                                elseif (itemSubType=="Enchanting") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 57;
                                                                end 
                                                        elseif(itemType=="Reagent") then 
                                                                GT_BS_PreScannedItems[itemName].sort = 895;
                                                        elseif(itemType=="Weapon") then 
                                                                GT_BS_PreScannedItems[itemName].sort = 700;
                                                                if (itemSubType=="Fishing Pole") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 39 - 100;
                                                                elseif (itemSubType=="Miscellaneous") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 38 - 100;
                                                                elseif (itemSubType=="Thrown") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 9 - 200;
                                                                else GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 50;
                                                                end 
                                                        elseif(itemType=="Armor") then 
                                                                GT_BS_PreScannedItems[itemName].sort = 600;
                                                                if (itemSubType=="Shield") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 60;
                                                                elseif (itemSubType=="Cloth") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 59;
                                                                elseif (itemSubType=="Leather") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 58;
                                                                elseif (itemSubType=="Mail") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 57;
                                                                elseif (itemSubType=="Plate") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 56;
                                                                elseif (itemSubType=="Miscellaneous") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 37;
                                                                end 
                                                        elseif(itemType=="Recipe") then 
                                                                GT_BS_PreScannedItems[itemName].sort = 500;
                                                                if (itemSubType=="Book") then GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 59;
                                                                else GT_BS_PreScannedItems[itemName].sort = GT_BS_PreScannedItems[itemName].sort + 50;
                                                                end
                                                        elseif(itemType=="Projectile") then 
                                                                GT_BS_PreScannedItems[itemName].sort = 450;
                                                        elseif(itemType=="Consumable") then 
                                                                GT_BS_PreScannedItems[itemName].sort = 350;
                                                        elseif(itemType=="Container") then 
                                                                GT_BS_PreScannedItems[itemName].sort = 250;
                                                        else GT_BS_PreScannedItems[itemName].sort = 50; end
                                                else
                                                        GT_BS_PreScannedItems[itemName].sort = 10000 - (bag_id+2)*100 - (slot_id+2);
                                                end
                                        else
                                                GT_BS_PreScannedItems[itemName].number = GT_BS_PreScannedItems[itemName].number + count;
                                        end
                                end
                        end
                end
        end
end

function GT_BS_Finalize()
        --Array of items that will be saved in SavedVariables.lua
        --Initiated as empty, if BankScan is not called during the session all data will be wiped upon logout
        GT_BS_ScannedItems = {};
        
        for itemName, param in pairs(GT_BS_PreScannedItems) do
                local element = {name = itemName, description = param.description, 
                                        number = param.number, pic = param.pic, quality = param.quality,
                                        sort = param.sort, type = param.type, subtype = param.subtype, id = param.id};
                table.insert(GT_BS_ScannedItems, element);
        end
        GT_BS_PreScannedItems = {};
        MoneyScanned = nil;
        
        --Sorting done in the following way:
        --first sort according to sort function, then alphabetically by subtype then by quality, then alphabeticaly by name
        table.sort(GT_BS_ScannedItems, function(i,j) return ((i.sort>j.sort) or (i.sort==j.sort and i.subtype<j.subtype) or 
                                                                                (i.sort==j.sort and i.subtype==j.subtype and i.quality>j.quality) or
                                                                                (i.sort==j.sort and i.subtype==j.subtype and i.quality==j.quality and i.name<j.name)) end);
        
      for itemName, param in pairs(GT_BS_ScannedItems) do
                GT_BS_ScannedItems[itemName].name = " "..param.name.." ";
                GT_BS_ScannedItems[itemName].number = " "..param.number.." ";
                GT_BS_ScannedItems[itemName].quality = " "..param.quality.." ";
        end 
        GT_BS_Date = " "..date("%m/%d/%y").." ";
        GT_Debug("BS Date: "..GT_BS_Date);
end
        
---------------------------------------------------------------
------------------Incoming Mail functions----------------------
---------------------------------------------------------------

--Scans inventory for empty slots and stores the list of them
--in global variable availableSlots
function GT_IM_ScanSlots()
local index, bag_id, slot_id, i;
        GT_Debug("ScanSlots.");
        if (MailOpened and State == 0) then
                
                GT_IM_Message:Show();
                
                numSlots = 0;
                --availableSlots = nil;
                availableSlots = {};
                
                for index, bag_id in {4,3,2,1,0} do
                        if (GetContainerNumSlots(bag_id)) then
                                for slot_id = GetContainerNumSlots(bag_id), 1, -1 do
                                        if (not GetContainerItemLink(bag_id, slot_id)) then
                                                availableSlots[numSlots+1] = {bag_id = bag_id, slot_id = slot_id};
                                                numSlots = numSlots+1;
                                        end
                                end
                        end
                end
                
                emptySlots = numSlots;
                
                GT_Debug("Empty space is scanned. There are "..numSlots.." empty slots.");
                
                if (numSlots < 1) then 
                        GT_Echo(MSG_IM_NOBAG);
                        State = -1;
                        return;
                end
                
                State = 1;
                From = GT_IM_NumMailedItems[Position] + 1;
                currentMessage = 1;
                --GT_IM_Update:Show();
        end
end

--Takes mail from the mailbox
function GT_IM_GrabMail()
        GT_IM_Update:Hide();
        local index, bag_id, slot_id, i;
        GT_Debug("GrabMail is called.");
        if (MailOpened and State == 1) then
                
                GT_Debug("------>Next item. "..currentMessage.." out of "..GetInboxNumItems());
                if (GetInboxNumItems() < currentMessage) then 
                        GT_Debug("End of messages."); 
                        State = 10; 
                        GT_IM_ScanItems(); 
                        return; 
                end
                
                if (emptySlots<=1) then 
                        GT_Debug("End of slots."); 
                        State = 10; 
                        GT_IM_ScanItems(); 
                        return; 
                end
                
                local sender, money, CODAmount, hasItem;
                _, _, sender, _, money, CODAmount, _, hasItem = GetInboxHeaderInfo(currentMessage);
                
                while ((not hasItem and money==0) or CODAmount>0) do
                        GT_Debug("Message has no item nor cash or is COD - skipping.");
                        currentMessage = currentMessage + 1;
                        if (currentMessage > GetInboxNumItems()) then
                                GT_Debug("End of messages.");
                                State = 10;
                                GT_IM_ScanItems();
                                return; 
                        end
                        _, _, sender, _, money, CODAmount, _, hasItem = GetInboxHeaderInfo(currentMessage);
                end
                
                local _item = "None";
                local _pic = "INV_Misc_QuestionMark";
                GT_Debug("Grabbing stuff from message. From: "..sender);
                
                if (hasItem) then 
                        GT_Debug("Taking item ...");
                        TakeInboxItem(currentMessage);
                        _item = "Unknown";
                        emptySlots = emptySlots - 1;
                end
                
                if (money>0) then 
                        if (_item == "None") then 
                                GT_Debug("No item, but there's money, taking ...");
                                TakeInboxMoney(currentMessage); 
                                _pic = "INV_Misc_Coin_01";
                                
                        elseif (_item == "Unknown") then
                                GT_Debug("There's money AND item ...");
                                State = 2;
                                
                        else 
                                GT_Debug("WTF?????");
                                State = -1;
                                
                        end
                end
                
                GT_Debug("Grabbing complete.");
                
                --Save info on current item in the array
                GT_IM_NumMailedItems[Position] = GT_IM_NumMailedItems[Position] + 1;
                GT_IM_MailedItems[Position][GT_IM_NumMailedItems[Position]] = {description="  ".._item.." ",
                                                                                                                                                name=" ".._item.." ", 
                                                                                                                                                number=" ".._item.." ",
                                                                                                                                                pic=" ".._pic.." ", 
                                                                                                                                                quality=" ".._item.." ",
                                                                                                                                                from=" "..sender.." ",
                                                                                                                                                coin=" "..money.." ",
                                                                                                                                                when=" "..date("%m/%d/%y").." ",
                                                                                                                                                id=" 00000 ",
                                                                                                                                                type=" None ",
                                                                                                                                                subtype=" None "};
                
                To = GT_IM_NumMailedItems[Position];
        GT_Debug("From = "..From.." To = "..To);
                
                if (State == 1) then 
                        if (string.find(sender, "Auction") and string.find(sender, "House")) then 
                                State = 3; 
                        else 
                                State = 4; 
                        end
                end
                
                return;
                
        --Item was taken - time to take the money
        elseif (MailOpened and State == 2) then
        TakeInboxMoney(currentMessage);
                State = 4;
                return;
                
        --Item from AH was taken, waiting for message to disapear
        elseif (MailOpened and State == 3) then
                GT_Debug("AH - waiting ...");
                State = 1;
                return;
                
        --Everything from the message was taken - deleting the message
        elseif (MailOpened and State == 4) then
                GT_Debug("Deleting ...");
                DeleteInboxItem(currentMessage);
                State = 1;
                return; 
                
        else
                GT_Debug("Just doing nothing.");
        end
end

--Scans global variable availableSlots for items, if found - updates MailedItems.
function GT_IM_ScanItems()
        GT_Debug("ScanItem is called.");
        if (MailOpened and State == 10) then
                
                if (To < From) then 
                        State = 11; 
                        GT_IM_Update:Hide();
                        GT_IM_Message:Hide();
                        GT_Echo(MSG_IM_SUCCESS);
                        return; 
                end
                
                local bag_id, slot_id, count, texture, itemName, i, itemQuality, itemDesc, itemType, itemSubType, itemId;
                
                bag_id = availableSlots[numSlots].bag_id;
                slot_id = availableSlots[numSlots].slot_id;
                GT_Debug("Checking: "..bag_id..", "..slot_id);
                if (not GT_GetItemInfo(bag_id, slot_id)) then return; end
                
                for i = From, To, 1 do 
                        GT_Debug("Checking: "..bag_id..", "..slot_id);
                        if (bag_id > -1 and slot_id > -1) then
                                itemName, itemQuality, itemDesc, count, texture, itemType, itemSubType, itemId = GT_GetItemInfo(bag_id, slot_id);
                        else
                                itemName = "Error";
                                itemQuality = "1";
                                itemDesc = "Error has occured.";
                                count = "1";
                                texture = "INV_Misc_QuestionMark";
                        end
                        
                        --if (not itemName) then return; end
                        
                        if (GT_IM_MailedItems[Position][i].name == " None ") then
                                GT_Debug("Skipping...");
                                GT_IM_MailedItems[Position][i].description = " No item ";
                                GT_IM_MailedItems[Position][i].name = " None ";
                                GT_IM_MailedItems[Position][i].pic = " INV_Misc_Coin_01 ";
                                GT_IM_MailedItems[Position][i].number = " 0 ";
                                GT_IM_MailedItems[Position][i].quality = " 1 ";
                                GT_IM_MailedItems[Position][i].id = " 00000 ";
                                GT_IM_MailedItems[Position][i].type = " None ";
                                GT_IM_MailedItems[Position][i].subtype = " None ";
                        else
                                if (not itemName) then From = i; GT_Debug("Ejecting..."); return; end
                                if (numSlots > 0) then
                                        availableSlots[numSlots] = nil;
                                        numSlots = numSlots - 1;
                                end
                                
                                GT_Debug("itemName='"..GT_IM_MailedItems[Position][i].name.."', replacing with '"..itemName.."'");
                                GT_Debug("Changing...");
                                GT_IM_MailedItems[Position][i].number = " "..count.." ";
                                GT_IM_MailedItems[Position][i].quality = " "..itemQuality.." ";
                                GT_IM_MailedItems[Position][i].description = " "..itemDesc.." ";
                                GT_IM_MailedItems[Position][i].name = " "..itemName.." ";
                                GT_IM_MailedItems[Position][i].pic = " "..texture.." ";
                                GT_IM_MailedItems[Position][i].id = " "..itemId.." ";
                                GT_IM_MailedItems[Position][i].type = " "..itemType.." ";
                                GT_IM_MailedItems[Position][i].subtype = " "..itemSubType.." ";
                                
                                if (numSlots > 0) then 
                                        bag_id = availableSlots[numSlots].bag_id;
                                        slot_id = availableSlots[numSlots].slot_id;
                                else
                                        bag_id = -1;
                                        slot_id = -1;
                                end
                        end
                end
                
        State = 11;
        GT_IM_Update:Hide();
        GT_IM_Message:Hide();
        GT_Echo(MSG_IM_SUCCESS);
        end
end

--Transfers data from GT_IM_NumMailedItems to BS_GT_Saved in reverse order
function GT_IM_Save()
        local i, j;
        j = 0;
        BS_GT_Saved = {};
        for i = GT_IM_NumMailedItems[Position], 1, -1 do
                if (GT_IM_MailedItems[Position][i]) then
                        GT_IM_Saved[GT_IM_NumMailedItems[Position]+1-i-j] = GT_IM_MailedItems[Position][i];
                else
                        j = j + 1;
                end
        end
end

Generated by GNU Enscript 1.6.5.90.