vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
-- stuff for the startup log
local SW_SL_RegExCreate = 0;
local SW_SL_RegExAdded = 0;

function SW_SL_Add(msg)
        table.insert(SW_StartupLog, msg);
end
function SW_SL_AddTrailer(msg)
        SW_StartupLog[table.getn(SW_StartupLog)] = SW_StartupLog[table.getn(SW_StartupLog)].. msg;
end
function SW_SL_SetLastOk()
        SW_SL_AddTrailer(SW_SL["OK"]);
end
function SW_SL_Finalize()
        SW_SL_Add(SW_SL["MAP_REGEX"].." "..SW_SL_RegExAdded.."/"..SW_SL_RegExCreate);
        SW_DumpTable(SW_StartupLog,nil,1,true);
        SW_StartupLog = nil;
        
end

function SW_DEV_FFN(func)
        if func == nil then return; end
        if type(func) ~= "function" then
                return "Not a function";
        end
        local ret = "??";
        local vars = getfenv();
        for k,v in pairs(vars) do
                if type(v) == "function" then
                        if func == v then
                                return k;
                        end
                end
        end
        return ret;
end
function SW_DEV_FindVar(str, chkVal)
        local vars = getfenv();
        local sLen =string.len(str);
        SW_printStr( "------ "..str.." ------");
        for k,v in pairs(vars) do
                if chkVal then
                        if type(v) == "string" then
                                if string.find(v, str) then
                        
                                        SW_printStr(k.." ==> "..v);
                                end
                        end
                else
                        
                        if string.find(k, str) then
                                if type(v) == "string" then
                                        SW_printStr(k.." ==> "..v);
                                else
                                        SW_printStr(k.." ("..type(v)..")");
                                end
                        end
                end
        end
end
function SW_DEV_CC(hideCorrectlyOrdered)
        local s1, s2;
        local headPrinted = false;
        local startS, endS;
        local problematic = {};
        local mainEnding = {};
        local mainSDI = 0;
        SW_printStr("-------------SW_DEV_CC--------------");
        -- get all problematic regex
        -- (these end in a string capture.)
        local re = "(.+)%(%.%-%)(.-)$";
        for i,toCheck in ipairs(SW_EventRegexMap[SW_DEV_EVENTDUMMY]) do
                
                s1 = SW_RegEx_Lookup[toCheck]["r"];
                _,_,startS, endS = string.find(s1, re);
                
                if endS ~= nil and string.len( endS ) <=20 then
                        -- the end capture may not include another capture
                        if not (string.find(endS,"%(%.%-%)") or string.find(endS,"%(%%d%+%)") ) then
                        --SW_printStr(s1.."    "..endS);
                                problematic[s1] = {startS, endS, toCheck};
                                if mainEnding[endS] == nil then
                                        mainEnding[endS] = 1;
                                else
                                        mainEnding[endS] = mainEnding[endS] + 1;
                                end
                        end
                end             
        end
        SW_DumpTable(mainEnding);
        
        --SW_DumpTable(problematic);
        
        for k, v in pairs(problematic) do
                headPrinted = false;
                --s2 = v[1].."(.-)"..v[2];
                s2 = v[1];
                mainSDI = SW_DEV_GetDummyIndex(k);
                
                for i,toCheck in ipairs(SW_EventRegexMap[SW_DEV_EVENTDUMMY]) do
                        s1 = SW_RegEx_Lookup[toCheck]["r"];
                         
                        if string.sub(s1,1,string.len(s2))== s2 then
                                -- it will collide with istelf.. 
                                if k ~= s1 then
                                        if (not hideCorrectlyOrdered) or (mainSDI < SW_DEV_GetDummyIndex(s1)) then

                                                if not headPrinted then
                                                        SW_printStr(" ");
                                                        SW_printStr("----CHECK "..v[3].." "..k);
                                                        headPrinted = true;
                                                end
                                                SW_printStr(toCheck.."  "..s1.."  LateSort:"..((SW_RegEx_Lookup[toCheck]["ls"]) or "NO"));
                                                
                                        end
                                end
                        end
                end
        end
        
end
function SW_DEV_GetDummyIndex(regEx)
        
        for i,toCheck in ipairs(SW_EventRegexMap[SW_DEV_EVENTDUMMY]) do
                if regEx == SW_RegEx_Lookup[toCheck]["r"] then
                        return i;
                end
        end
end
-- this function is used to create "junk" for testing
--[[
-- need this to map var names to var values
local SW_G_VARS = getfenv();
-- note to self check GetCVar
local junkIndex =0;

SW_DEV_JUNK_STRINGS ={};

local function SW_CreateJunk(varName)
        local strMain = getglobal(varName);
        local str ="";
        
        if strMain == nil then return end;
        
        for i=1,SW_DEV_ITEMS_PER_REGEX do
                
                --[[
                str = string.gsub(strMain, '(%%(%d?)$?([sd]))',
                        function(all,num,type)
                                if type == 's' then
                                        return (string.rep(string.char(math.random(97,122)), math.random(3,5)));
                                else
                                        return (math.random(1000));
                                end
                        end);
                --]]
                str = string.gsub(strMain, '(%%(%d?)$?([sd]))',
                        function(all,num,type)
                                if type == 's' then
                                        return ("STRING");
                                else
                                        return (12345);
                                end
                        end);
                table.insert(SW_DEV_JUNK_STRINGS, str);
        end
end
--]]
--[[
 used this to find ending collisions
 only "bad" one found in en,de,fr is  en: PERIODICAURAHEALSELFSELF
 fr has some with extra attack messages, but not using these atm
SW_EndingTest = {};
SW_EndingCol = {};

function SW_TestEnding(str)
        local tmpStr = string.gsub(str, "(%%%d?$?s%.)$", "");
        
        for k,v in pairs(SW_EndingTest) do
                if string.sub(k,1,string.len(tmpStr))==tmpStr then
                        if SW_EndingCol[tmpStr] == nil then
                                SW_EndingCol[tmpStr] = 1;
                        else
                                SW_EndingCol[tmpStr] = SW_EndingCol[tmpStr] +1;
                        end
                        
                end
        end
        if SW_EndingTest[str] == nil then
                SW_EndingTest[str] = 0;
        end
end
--]]
--this converts a GlobalVariable to a regex we can use  
-- and add it to SW_RegEx_Lookup
local function SW_InitVar(varName,types,fromSelf,toSelf,isCrit,lateSort)
        local str = getglobal(varName);
        --SW_TestEnding(str);
        --check if we are trying to work on a global thats not available
        if str == nil then 
                SW_printStr("SW_InitVar varName NIL: "..varName);
                return 
        end;
        --SW_CreateJunk(varName);
        
        if types == nil then return end;
        
        --fixes ambiguous strings
        -- fix log strings is a localized function
        local strTmp = SW_FixLogStrings(str);
        if str ~= strTmp then
                setglobal(varName, strTmp);
                str = strTmp;
        end
        
        SW_SL_RegExCreate = SW_SL_RegExCreate +1;
        SW_RegEx_Lookup[varName] ={};
        
        -- "p"  stands for positions maps found for numbered vals (e.g. %3$s)
        -- in a different langugage these might be used in a different order
        SW_RegEx_Lookup[varName]["p"] ={}; 
        
        SW_RegEx_Lookup[varName]["types"] = types; 
        if lateSort then
                SW_RegEx_Lookup[varName]["ls"] = 1;
        end
        if fromSelf then
                SW_RegEx_Lookup[varName]["fromSelf"] = 1;
        end
        if toSelf then
                SW_RegEx_Lookup[varName]["toSelf"] = 1;
        end
        if isCrit then
                SW_RegEx_Lookup[varName]["isCrit"] = 1;
        end
        local index=0;
        local needPosLookup = false;
        
        
        -- first we have to "sanitze" the string  ^()%.[]*+-?  are special chars in a regex (dont escape the $ and %)
        -- so we are escaping these with %
        str = string.gsub(str, "([%.%(%)%+%-%?%[%]%^])", "%%%1");
        
        -- the inner function actually does the work
        str = string.gsub(str, '(%%(%d?)$?([sd]))',
                function(all,num,type) -- e.g. %3$s all = %3$s  num=3 type=s
                        index = index+1;
                        --1.0.2 , fixed the french version bug through "tonumber .. omg DOH .. oh well
                        -- this will help all non englisch versions
                        SW_RegEx_Lookup[varName]["p"][index] = tonumber(num);
                        if num ~= "" then 
                                -- if num is "" then the string e.g. only used %s and not %1$s
                            -- and we dont need a lookup - its already in order
                            needPosLookup = true;
                        end
                        
                        --this is the actual replacement that makes the regex
                        -- use non greedy for strings
                        if type == 's' then
                                return ('(.-)');
                        else
                                return ('(%d+)');
                        end
                end);
                
        -- saves how many captures to expect later using this regex
        SW_RegEx_Lookup[varName]["i"] = index; 
        
        --generate maps for heal dmg etc info
        if index == getn(types) then
                local playerName = "";
                local mm = {};
                local medm = {};
                local i;
                local max = getn(types);

                --1 = target
                --2 = caster/attacker/initiator
                --3 = someString (normally spell names, or item names)
                -- 51 = dmg 52 = heal
                --{from,to,dmg,heal, what}
                for i, val in ipairs(types) do
                        if val == 2 then
                                mm[1] = i;
                                medm[1] = i;
                        elseif val == 1 then
                                mm[2] = i;
                                medm[2] = i;
                        elseif val == 51 then
                                mm[3] = i;
                                medm[3] = i;
                        elseif val == 52 then
                                mm[4] = i;
                                medm[4] = i;
                        elseif val == 3 then
                                mm[5] = i;
                                medm[5] = i;
                        elseif val == 7 then
                                mm[6] = i;
                                medm[6] = i;
                        end
                end
                if fromSelf then
                        mm[1]= -1;
                end
                if toSelf then
                        mm[2]= -1;
                end     
                
                
                SW_RegEx_Lookup[varName]["basicInfo"] = mm;
                --SW_RegEx_Lookup[varName]["fullInfo"] = medm;  
        else
                SW_printStr(RED_FONT_COLOR_CODE.."SW_InitVar "..varName.." "..index.."~="..getn(types).." caputerN~=TypeN" , 1);
        end
        
        if  needPosLookup then
                -- check if we really do need it
                -- could be in order anyways
                needPosLookup = false;
                for k, v in pairs(SW_RegEx_Lookup[varName]["p"]) do 
                        -- make k, v numbers, so they will compare
                        -- k,v are of different types so this wouldn't work otherwise
                        k = k+0;
                        v = v+0;
                        if k~=v then
                                needPosLookup = true;
                                break;
                        end
                end
        end
        -- now we are sure if we need it or not
        if not needPosLookup then
                -- %s %d etc. used info is "in order"
                -- or %1$s %2$d etc. was used but all in correct order
                -- just junk it
                SW_RegEx_Lookup[varName]["p"] = nil;
        end

        --if string.sub(str,1,1) == "(" then
                --SW_RegEx_Lookup[varName]["r"] = str; -- the regex
        --else
                SW_RegEx_Lookup[varName]["r"] = "^"..str; -- the regex
        --end
        --[[ Interesting have to comment this out so wow will work??
                maybe because this is a local function ?
        if SW_DEV_CREATE_JUNK_STRINGS then
                SW_CreateJunk(varName);
        end
        ]]--
end

--------------------- the global vars to define a regex for -------------------------------
function SW_CreateRegexFromGlobals()
        -- take these out while finding matches and collisions
        --SW_InitVar("VULNERABLE_TRAILER");
        --SW_InitVar("ABSORB_TRAILER");
        --SW_InitVar("BLOCK_TRAILER");
        --SW_InitVar("RESIST_TRAILER");
        SW_SL_Add(SW_SL["REGEX"]);
        --[[ new way, a lot more info
                name of string var,
                Arrray of types 
                        The array is mapped 1 to 1 to the captures AFTER the captures have been sorted
                        (for different languages they may be in different order)
                        
                        1 = target
                        2 = caster/attacker/initiator
                        3 = someString (normally spell names, or item names)
                        4 = unused 
                        5x = Number
                        6x = number 2
                                where x
                                1= Damage
                                2 = Heal
                                3 = Other
                                4 = LeechFrom amount(victim of leech )
                                5 = LeechTo amount (leech transferred to)
                        7 = School
                        8 = LeechFrom (String what is leeched health, mana, etc)
                        9 = LeechTo     (string what has been transferred healt, mana, etc)
                        10 = Leech benefit (the person the got the "good side" of the leech
                        (leech and drain use the same types, some fields are just not set)
                After the array:
                fromself, (did one self start the cast/attack? )
                toself, (did one self get the heal/hit...)
                iscrit, (is this a crit?)
                lateSort (special indicated to check these last; used in recuCheck, 
                                used to push back some regex that capture to early)
                                
        note to self... new in 1.9 true if this locale:
        LOCALE_enGB, LOCALE_enUS, LOCALE_frFR, LOCALE_deDE, LOCALE_koKR, LOCALE_zhCN, LOCALE zhTW 
                        
        ]]--
        if (LOCALE_frFR) then
                -- captures to early in fr version
                SW_InitVar("COMBATHITCRITOTHEROTHER",{2,1,51},nil,nil,true,true);
                SW_InitVar("COMBATHITCRITSCHOOLOTHEROTHER",{2,1,51,7},nil,nil,true,true);
        else
                SW_InitVar("COMBATHITCRITOTHEROTHER",{2,1,51},nil,nil,true,nil);
                SW_InitVar("COMBATHITCRITSCHOOLOTHEROTHER",{2,1,51,7},nil,nil,true,nil);
        end
        
        SW_InitVar("COMBATHITCRITOTHERSELF",{2,51},nil,true,true,nil);
        SW_InitVar("COMBATHITCRITSCHOOLOTHERSELF",{2,51,7},nil,true,true,nil);
        SW_InitVar("COMBATHITCRITSCHOOLSELFOTHER",{1,51,7},true,nil,true,nil);
        SW_InitVar("COMBATHITCRITSELFOTHER",{1,51},true,nil,true,nil);
        
        if (LOCALE_zhCN or LOCALE_zhTW) then
                SW_InitVar("COMBATHITOTHEROTHER",{2,1,51},nil,nil,nil,true);
                SW_InitVar("COMBATHITSCHOOLOTHEROTHER",{2,1,51,7},nil,nil,nil,true);
                SW_InitVar("COMBATHITSCHOOLOTHERSELF",{2,51,7},nil,true,nil,true);
        else
                SW_InitVar("COMBATHITOTHEROTHER",{2,1,51},nil,nil,nil,nil);
                SW_InitVar("COMBATHITSCHOOLOTHEROTHER",{2,1,51,7},nil,nil,nil,nil);
                SW_InitVar("COMBATHITSCHOOLOTHERSELF",{2,51,7},nil,true,nil,nil);
        end
        
        SW_InitVar("COMBATHITOTHERSELF",{2,51},nil,true,nil,nil);
        SW_InitVar("COMBATHITSCHOOLSELFOTHER",{1,51,7},true,nil,nil,nil);
        SW_InitVar("COMBATHITSELFOTHER",{1,51},true,nil,nil,nil);
        SW_InitVar("DAMAGESHIELDOTHEROTHER",{2,51,7,1},nil,nil,nil,nil);
        SW_InitVar("DAMAGESHIELDOTHERSELF",{2,51,7},nil,true,nil,nil);
        SW_InitVar("DAMAGESHIELDSELFOTHER",{51,7,1},true,nil,nil,nil);
        SW_InitVar("ERR_COMBAT_DAMAGE_SSI",{2,1,51},nil,nil,nil,true);
        SW_InitVar("HEALEDCRITOTHEROTHER",{2,3,1,52},nil,nil,true,nil);
        SW_InitVar("HEALEDCRITOTHERSELF",{2,3,52},nil,true,true,nil);
        SW_InitVar("HEALEDCRITSELFOTHER",{3,1,52},true,nil,true,nil);
        SW_InitVar("HEALEDCRITSELFSELF",{3,52},true,true,true,nil);
        SW_InitVar("HEALEDOTHEROTHER",{2,3,1,52},nil,nil,nil,nil);
        SW_InitVar("HEALEDOTHERSELF",{2,3,52},nil,true,nil,nil);
        SW_InitVar("HEALEDSELFOTHER",{3,1,52},true,nil,nil,nil);
        SW_InitVar("HEALEDSELFSELF",{3,52},true,true,nil,nil);
        SW_InitVar("PERIODICAURADAMAGEOTHEROTHER",{1,51,7,2,3},nil,nil,nil,nil);
        SW_InitVar("PERIODICAURADAMAGEOTHERSELF",{51,7,2,3},nil,true,nil,nil);
        SW_InitVar("PERIODICAURADAMAGESELFOTHER",{1,51,7,3},true,nil,nil,nil);
        SW_InitVar("PERIODICAURADAMAGESELFSELF",{51,7,3},true,true,nil,nil);
        SW_InitVar("PERIODICAURAHEALOTHEROTHER",{1,52,2,3},nil,nil,nil,nil);
        SW_InitVar("PERIODICAURAHEALOTHERSELF",{52,2,3},nil,true,nil,nil);
        SW_InitVar("PERIODICAURAHEALSELFOTHER",{1,52,3},true,nil,nil,nil);
        
        if LOCALE_enGB or LOCALE_enUS then
                -- captures to early in en versions
                SW_InitVar("PERIODICAURAHEALSELFSELF",{52,3},true,true,nil,true);
        else
                SW_InitVar("PERIODICAURAHEALSELFSELF",{52,3},true,true,nil,nil);
        end
        
        SW_InitVar("PET_DAMAGE_PERCENTAGE",{53},nil,nil,nil,nil);
        SW_InitVar("SPELLEXTRAATTACKSOTHER",{1,53,3},nil,nil,nil,nil);
        SW_InitVar("SPELLEXTRAATTACKSOTHER_SINGULAR",{1,53,3},nil,nil,nil,nil);
        SW_InitVar("SPELLEXTRAATTACKSSELF",{53,3},nil,true,nil,nil);
        SW_InitVar("SPELLEXTRAATTACKSSELF_SINGULAR",{3,53},nil,true,nil,nil);
        SW_InitVar("SPELLHAPPINESSDRAINOTHER",{1,2,53},nil,nil,nil,nil);
        SW_InitVar("SPELLHAPPINESSDRAINSELF",{1,53},true,nil,nil,nil);
        SW_InitVar("SPELLLOGCRITOTHEROTHER",{2,3,1,51},nil,nil,true,nil);
        SW_InitVar("SPELLLOGCRITOTHERSELF",{2,3,51},nil,true,true,nil);
        SW_InitVar("SPELLLOGCRITSCHOOLOTHEROTHER",{2,3,1,51,7},nil,nil,true,nil);
        SW_InitVar("SPELLLOGCRITSCHOOLOTHERSELF",{2,3,51,7},nil,true,true,nil);
        SW_InitVar("SPELLLOGCRITSCHOOLSELFOTHER",{3,1,51,7},true,nil,true,nil);
        SW_InitVar("SPELLLOGCRITSCHOOLSELFSELF",{3,51,7},true,true,true,nil);
        SW_InitVar("SPELLLOGCRITSELFOTHER",{3,1,51},true,nil,true,nil);
        SW_InitVar("SPELLLOGCRITSELFSELF",{3,51},true,true,true,nil);
        SW_InitVar("SPELLLOGOTHEROTHER",{2,3,1,51},nil,nil,nil,nil);
        SW_InitVar("SPELLLOGOTHERSELF",{2,3,51},nil,true,nil,nil);
        SW_InitVar("SPELLLOGSCHOOLOTHEROTHER",{2,3,1,51,7},nil,nil,nil,nil);
        SW_InitVar("SPELLLOGSCHOOLOTHERSELF",{2,3,51,7},nil,true,nil,nil);
        SW_InitVar("SPELLLOGSCHOOLSELFOTHER",{3,1,51,7},true,nil,nil,nil);
        SW_InitVar("SPELLLOGSCHOOLSELFSELF",{3,51,7},true,true,nil,nil);
        SW_InitVar("SPELLLOGSELFOTHER",{3,1,51},true,nil,nil,nil);
        SW_InitVar("SPELLLOGSELFSELF",{3,51},true,true,nil,nil);
        
        if LOCALE_enGB or LOCALE_enUS then
                SW_InitVar("SPELLPOWERDRAINOTHEROTHER",{2,3,54,8,1},nil,nil,nil,true);
                SW_InitVar("SPELLPOWERDRAINOTHERSELF",{2,3,54,8},nil,true,nil,true);
        else
                SW_InitVar("SPELLPOWERDRAINOTHEROTHER",{2,3,54,8,1},nil,nil,nil,nil);
                SW_InitVar("SPELLPOWERDRAINOTHERSELF",{2,3,54,8},nil,true,nil,nil);
        end
        SW_InitVar("SPELLPOWERDRAINSELFOTHER",{3,54,8,1},true,nil,nil,nil);
        SW_InitVar("SPELLPOWERLEECHOTHEROTHER",{2,3,54,8,1,10,65,9},nil,nil,nil,nil);
        SW_InitVar("SPELLPOWERLEECHOTHERSELF",{2,3,54,8,10,65,9},nil,true,nil,nil);
        SW_InitVar("SPELLPOWERLEECHSELFOTHER",{3,54,8,1,65,9},true,nil,nil,nil);
        SW_InitVar("SPELLSPLITDAMAGEOTHEROTHER",{2,3,1,51},nil,nil,nil,nil);
        SW_InitVar("SPELLSPLITDAMAGEOTHERSELF",{2,3,51},nil,true,nil,nil);
        SW_InitVar("SPELLSPLITDAMAGESELFOTHER",{2,1,51},nil,nil,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_DROWNING_OTHER",{1,51},nil,nil,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_DROWNING_SELF",{51},nil,true,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_FALLING_OTHER",{1,51},nil,nil,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_FALLING_SELF",{51},nil,true,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_FATIGUE_OTHER",{1,51},nil,nil,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_FATIGUE_SELF",{51},nil,true,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_FIRE_OTHER",{1,51},nil,nil,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_FIRE_SELF",{51},nil,true,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_LAVA_OTHER",{1,51},nil,nil,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_LAVA_SELF",{51},nil,true,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_SLIME_OTHER",{1,51},nil,nil,nil,nil);
        SW_InitVar("VSENVIRONMENTALDAMAGE_SLIME_SELF",{51},nil,true,nil,nil);

        --1.4 removed in wow 1.10
        -- it doesn't hurt to leave them in for easy transition 1.9->1.10
        --[[
        SW_InitVar("POWERGAIN_OTHER",{1,53,3},nil,nil,nil,true);
        SW_InitVar("POWERGAIN_SELF",{53,3},nil,true,nil,true);
        SW_InitVar("GENERICPOWERGAIN_OTHER",{1,53,3},nil,nil,nil,true);
        SW_InitVar("GENERICPOWERGAIN_SELF",{53,3},nil,true,nil,true);
        --]]
        
        --1.4 wow 1.10 changed powergain stuff
        -- mana/ health etc isnt really a "LeechTo" but this fits best
        -- 1.5.1 selfself and selfother changed to late sort
        SW_InitVar("POWERGAINOTHEROTHER",{1,53,9,2,3},nil,nil,nil,nil);
        SW_InitVar("POWERGAINOTHERSELF",{53,9,2,3},nil,true,nil,nil);
        SW_InitVar("POWERGAINSELFOTHER",{1,53,9,3},true,nil,nil,true);
        SW_InitVar("POWERGAINSELFSELF",{53,9,3},true,true,nil,true);
        --1.4  wow 1.10 aura stuff
        SW_InitVar("AURAAPPLICATIONADDEDOTHERHARMFUL",{1,3,53},nil,nil,nil,nil);
        SW_InitVar("AURAAPPLICATIONADDEDOTHERHELPFUL",{1,3,53},nil,nil,nil,nil);
        SW_InitVar("AURAAPPLICATIONADDEDSELFHARMFUL",{3,53},nil,true,nil,nil);
        SW_InitVar("AURAAPPLICATIONADDEDSELFHELPFUL",{3,53},nil,true,nil,nil);
        
        -- 1.5.1 for decursing (could be used for more)
        SW_InitVar("SIMPLECASTOTHEROTHER",{2,3,1},nil,nil,nil,nil);
        SW_InitVar("SIMPLECASTOTHERSELF",{2,3},nil,true,nil,nil);
        SW_InitVar("SIMPLECASTSELFOTHER",{3,1},true,nil,nil,nil);
        SW_InitVar("SIMPLECASTSELFSELF",{3},true,true,nil,true);
        
        -- this one is very generic %s casts %s
        -- could use this to count totem placement
        --SW_InitVar("SPELLCASTGOOTHER",{2,3},nil,nil,nil,true);
        
        -- 1.5.3.beta.1 Added but not used, but will cause blocking events w/o
        -- noticed this through the curse patchwerk kill video ;)
        SW_InitVar("COMBATLOG_HONORGAIN",{1,3,53},true,nil,nil,nil);
        
        SW_SL_SetLastOk();
end

local function SW_AddToMap(eventName, regexName, map)
        if map == nil then map = SW_EventRegexMap; end
        
        -- first check if we have the info needed
        --added this for WOW 1.10 POWERGAINXX changes
        if SW_RegEx_Lookup[regexName] == nil then
                --DEFAULT_CHAT_FRAME:AddMessage(regexName);
                
                return;
        end
        if SW_RegEx_Lookup[regexName]["r"] == nil then return; end
        
        if map[eventName] == nil then
                map[eventName] ={};
        end
        --use insert we want to sort this later using table.sort 
        table.insert(map[eventName], regexName);        
        
        SW_SL_RegExAdded = SW_SL_RegExAdded +1;
end

--[[ this resorts SW_EventRegexMap based on the regular expression
        to be used
        This is done to minimize the chance of a collision
        rule 1 -> anything that starts with a string and not a capture goes first
        rule 2 -> if it starts with a capture not followed by a space it goes first
        rule 3 - > less captures go first
        rule 4 -> longer strings go first
]]--
local function recuCheck(a, b, opt)

        local l = SW_RegEx_Lookup[a]["r"];
        local r = SW_RegEx_Lookup[b]["r"];
        
        if opt == nil then
                local sl = string.sub(l,2,2);
                local sr = string.sub(r,2,2);
                if sl == "(" then
                        if sr == "(" then
                                return recuCheck(a, b, 1);
                        else
                                return false;
                        end
                else
                        if sr == "(" then
                                return true;
                        else
                                return recuCheck(a, b, 1);
                        end
                end
        elseif opt == 1 then
                if SW_RegEx_Lookup[a]["ls"] and SW_RegEx_Lookup[b]["ls"] then
                        return recuCheck(a, b, 2);
                end
                if SW_RegEx_Lookup[a]["ls"] then 
                        return false;
                end
                if SW_RegEx_Lookup[b]["ls"] then 
                        return true;
                end
                return recuCheck(a, b, 2);
        elseif opt == 2 then
                local sl = string.sub(l,1,5);
                local sr = string.sub(r,1,5);
                local slf = string.sub(l,1,2);
                
                if sl == sr and slf == "^(" then
                        
                        sl = string.sub(l,6,6);
                        sr = string.sub(r,6,6);
                        if sl == sr then
                                return recuCheck(a, b, 3);
                        else
                                if sl == " " then
                                        return false;
                                elseif sr == " " then
                                        return true;
                                else
                                        return recuCheck(a, b, 3);
                                end
                        end
                else
                        return recuCheck(a, b, 3);
                end
                
        elseif opt == 3 then
                if  SW_RegEx_Lookup[a]["i"] == SW_RegEx_Lookup[b]["i"] then
                        return recuCheck(a, b, 4);
                else 
                        return SW_RegEx_Lookup[a]["i"] < SW_RegEx_Lookup[b]["i"];
                end
        elseif opt == 4 then
                        return  string.len(l) > string.len(r);
                        
        else
                return false;
        end
end

local function SW_finalizeMap()
        SW_SL_Add(SW_SL["MAP_SORT"]);
        
        for k,v in pairs(SW_EventRegexMap) do
                table.sort(v, 
                        function(a,b)
                                return recuCheck(a,b);
                        end);
        end
        
        SW_SL_SetLastOk();
        
end

function SW_CreateEventRegexMap()
        SW_SL_Add(SW_SL["MAP"]);
        
        -- first we need the "dummy" for non handeled events
        -- added an extra "dummy" for text only events --SW_DECURSEDUMMY
        for k,_ in pairs(SW_RegEx_Lookup) do
                if string.sub(k,1,string.len("SIMPLECAST"))=="SIMPLECAST" or string.sub(k,1,string.len("SPELLCASTGO"))=="SPELLCASTGO" then
                        SW_AddToMap(SW_DECURSEDUMMY, k);
                else
                        SW_AddToMap(SW_DEV_EVENTDUMMY, k);
                end
        end
        
        for k,v in pairs(SW_Map) do
                for _, regExName in pairs(v) do
                        SW_AddToMap(k, regExName);
                end
        end
        for k,v in pairs(SW_EnviroMap) do
                for _, regExName in pairs(v) do
                        SW_AddToMap(k, regExName, SW_EventRegexMapEnviro);
                end
        end
        
        SW_SL_SetLastOk();
        SW_finalizeMap();
        
        -- pulling the SW_TmpMap info here, its already sorted
        --[[
        for i,v in ipairs(SW_EventRegexMap[SW_DEV_EVENTDUMMY]) do
                local tmp = string.sub(SW_RegEx_Lookup[v]["r"],1,4);
                if tmp == "(.+)" then
                        tmp = string.sub(SW_RegEx_Lookup[v]["r"],5,5);
                        if tmp ~= " " then
                                if SW_TmpMap == nil then SW_TmpMap = {}; end
                                table.insert(SW_TmpMap, v);     
                        end
                end
        end
        --]]
end;
-- this is called if there was no direct Event->Regexp entry
-- and a regex was found using the event dummy
function SW_lateAdd(eventName, regexName, map, saveToMap, checkDupes)
        if checkDupes then
                for _,v  in ipairs(map[eventName]) do
                        if v == regexName then return; end
                end
        end
        SW_AddToMap(eventName, regexName, map);
        table.sort(map[eventName], 
                        function(a,b)
                                return recuCheck(a,b);
                        end);
        -- now add it to the map thats saved
        if saveToMap ~= nil then
                if saveToMap[eventName] == nil then
                        saveToMap[eventName] ={};
                end
                table.insert(saveToMap[eventName], regexName);  
        end
        
end
------------------------- Events to listen to --------------------------------

--[[ 
        1.5 added pausing and unpausing of data collection
        so changed the event definition here and split it into 2 parts
        events that have to be on always, and events that can be switched
--]]
SW_EventCollection = {
        SW_EventsMandatory = {
                "PLAYER_TARGET_CHANGED",
                "VARIABLES_LOADED",
                --"UNIT_COMBAT", hmm i wasn't using this?
                "UNIT_PET",
                "PARTY_MEMBERS_CHANGED",
                "PARTY_LEADER_CHANGED",
                "RAID_ROSTER_UPDATE",
                "PLAYER_ENTERING_WORLD",
                
                -- for joining
                "CHAT_MSG_GUILD",
                "CHAT_MSG_OFFICER",
                "CHAT_MSG_PARTY",
                "CHAT_MSG_RAID",
                "CHAT_MSG_CHANNEL",
                -- 1.5.3 added in wow 1.11
                "CHAT_MSG_RAID_LEADER",
                
                -- 1.5.beta.2 this better not be off DOH 
                "SPELLS_CHANGED",
        },
        SW_EventsSwitched = {
                "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS",
                "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES",
                "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS",
                "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES",
                "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS",
                "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES",
                "CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
                "CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
                "CHAT_MSG_COMBAT_FRIENDLY_DEATH",
                "CHAT_MSG_COMBAT_HONOR_GAIN",
                "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS",
                "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES",
                "CHAT_MSG_COMBAT_HOSTILE_DEATH",
                "CHAT_MSG_COMBAT_LOG_ERROR",
                "CHAT_MSG_COMBAT_LOG_MISC_INFO",
                "CHAT_MSG_COMBAT_PARTY_HITS",
                "CHAT_MSG_COMBAT_PARTY_MISSES",
                "CHAT_MSG_COMBAT_PET_HITS",
                "CHAT_MSG_COMBAT_PET_MISSES",
                "CHAT_MSG_COMBAT_SELF_HITS",
                "CHAT_MSG_COMBAT_SELF_MISSES",
                "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF",
                "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
                "CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF",
                "CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE",
                "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF",
                "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
                "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS",
                "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF",
                "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF",
                "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
                "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF",
                "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
                "CHAT_MSG_SPELL_PARTY_BUFF",
                "CHAT_MSG_SPELL_PARTY_DAMAGE",
                "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS",
                "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
                "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS",
                "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE",
                "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
                "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE",
                "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
                "CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",
                "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS",
                "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
                "CHAT_MSG_SPELL_PET_BUFF",
                "CHAT_MSG_SPELL_PET_DAMAGE",
                "CHAT_MSG_SPELL_SELF_BUFF",
                "CHAT_MSG_SPELL_SELF_DAMAGE",
                "PLAYER_REGEN_DISABLED",
                "PLAYER_REGEN_ENABLED",
                
                -- added for 1.3.0 to get mana efficiency
                "SPELLCAST_CHANNEL_START",
                "SPELLCAST_STOP",
                "SPELLCAST_FAILED",
                "SPELLCAST_INTERRUPTED",
                 
                -- added 1.4 for death count
                "CHAT_MSG_COMBAT_FRIENDLY_DEATH",
                "CHAT_MSG_COMBAT_HOSTILE_DEATH",
        },
        
}
function SW_UnpauseEvents()
        local coreFrame = getglobal("SW_CoreFrame");
        for i, val in ipairs(SW_EventCollection.SW_EventsSwitched) do
                coreFrame:RegisterEvent(val);
        end
        
end
function SW_PauseEvents()
        local coreFrame = getglobal("SW_CoreFrame");
        for i, val in ipairs(SW_EventCollection.SW_EventsSwitched) do
                coreFrame:UnregisterEvent(val);
        end
end
function SW_RegisterEvents()
        SW_SL_Add(SW_SL["EVENTS"]);
        
        for i, val in ipairs(SW_EventCollection.SW_EventsMandatory) do
                this:RegisterEvent(val);
        end
        
        --[[
        -- used to check what kinds of targets are tracked
        this:RegisterEvent("PLAYER_TARGET_CHANGED");
        --this:RegisterEvent("CHAT_MSG_CHANNEL_LIST");
        
        this:RegisterEvent("VARIABLES_LOADED");
        this:RegisterEvent("UNIT_COMBAT");
        this:RegisterEvent("UNIT_PET");
        this:RegisterEvent("PARTY_MEMBERS_CHANGED");
        -- 1.4.2 added leader change
        this:RegisterEvent("PARTY_LEADER_CHANGED");
        this:RegisterEvent("RAID_ROSTER_UPDATE");
        this:RegisterEvent("PLAYER_ENTERING_WORLD");
        --this:RegisterEvent("CHAT_MSG_AFK");
        --this:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE");
        --this:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE");
        --this:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL");
        --this:RegisterEvent("CHAT_MSG_CHANNEL_LIST");
        this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS");
        this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES");
        this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS");
        this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES");
        this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS");
        this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES");
        this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS");
        this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES");
        this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLY_DEATH");
        this:RegisterEvent("CHAT_MSG_COMBAT_HONOR_GAIN");
        this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS");
        this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES");
        this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH");
        this:RegisterEvent("CHAT_MSG_COMBAT_LOG_ERROR");
        this:RegisterEvent("CHAT_MSG_COMBAT_LOG_MISC_INFO");
        --this:RegisterEvent("CHAT_MSG_COMBAT_MISC_INFO");
        this:RegisterEvent("CHAT_MSG_COMBAT_PARTY_HITS");
        this:RegisterEvent("CHAT_MSG_COMBAT_PARTY_MISSES");
        this:RegisterEvent("CHAT_MSG_COMBAT_PET_HITS");
        this:RegisterEvent("CHAT_MSG_COMBAT_PET_MISSES");
        this:RegisterEvent("CHAT_MSG_COMBAT_SELF_HITS");
        this:RegisterEvent("CHAT_MSG_COMBAT_SELF_MISSES");
        --this:RegisterEvent("CHAT_MSG_COMBAT_XP_GAIN");
        --this:RegisterEvent("CHAT_MSG_DND");
        --this:RegisterEvent("CHAT_MSG_EMOTE");
        this:RegisterEvent("CHAT_MSG_GUILD");
        --this:RegisterEvent("CHAT_MSG_IGNORED");
        --this:RegisterEvent("CHAT_MSG_LOOT");
        --this:RegisterEvent("CHAT_MSG_MONSTER_EMOTE");
        --this:RegisterEvent("CHAT_MSG_MONSTER_SAY");
        --this:RegisterEvent("CHAT_MSG_MONSTER_WHISPER");
        --this:RegisterEvent("CHAT_MSG_MONSTER_YELL");
        this:RegisterEvent("CHAT_MSG_OFFICER");
        this:RegisterEvent("CHAT_MSG_PARTY");
        this:RegisterEvent("CHAT_MSG_RAID");
        this:RegisterEvent("CHAT_MSG_CHANNEL");
        --this:RegisterEvent("CHAT_MSG_SKILL");
        
        --this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_OTHER");
        --this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_PARTY");
        --this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_SELF");
        --this:RegisterEvent("CHAT_MSG_SPELL_BREAK_AURA");
        
        this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF");
        this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF");
        this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF");
        this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS");
        this:RegisterEvent("CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF");
        
        this:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF");
        this:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF");
        this:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE");
        
        this:RegisterEvent("CHAT_MSG_SPELL_PARTY_BUFF");
        this:RegisterEvent("CHAT_MSG_SPELL_PARTY_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS");
        this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_PET_BUFF");
        this:RegisterEvent("CHAT_MSG_SPELL_PET_DAMAGE");
        this:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF");
        this:RegisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE");
        
        --this:RegisterEvent("CHAT_MSG_SPELL_TRADESKILLS");
        --this:RegisterEvent("CHAT_MSG_SYSTEM");
        --this:RegisterEvent("CHAT_MSG_TEXT_EMOTE");
        --this:RegisterEvent("CHAT_MSG_WHISPER");
        --this:RegisterEvent("CHAT_MSG_WHISPER_INFORM");
        --this:RegisterEvent("CHAT_MSG_SAY");
        
        --this:RegisterEvent("SPELLCAST_STOP");
        --this:RegisterEvent("UNIT_HEALTH");
        
        -- added for 1.3.0 to get mana efficiency
        
        this:RegisterEvent("SPELLCAST_CHANNEL_START");
        --this:RegisterEvent("SPELLCAST_START");
        this:RegisterEvent("SPELLCAST_STOP");
        this:RegisterEvent("SPELLCAST_FAILED");
        this:RegisterEvent("SPELLCAST_INTERRUPTED");
        this:RegisterEvent("SPELLS_CHANGED");
         
         this:RegisterEvent("PLAYER_REGEN_DISABLED");
         this:RegisterEvent("PLAYER_REGEN_ENABLED");
           
        -- added 1.4 for death count
        this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLY_DEATH");
        this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH");
        --this:RegisterEvent("SPELLCAST_DELAYED");
        --this:RegisterEvent("SPELLCAST_CHANNEL_START");
        --this:RegisterEvent("SPELLCAST_CHANNEL_UPDATE");
        --]]
        SW_SL_SetLastOk();
end

--[[
        A wrapper arround timing
        If added to saved variables (and inited again)
        will retain cross session seconds ( and milliseconds)
        
        to save it accross sessions add myTimer to SavedVariables AND IN
        VARIABLES_LOADED: myTimer = SW_C_Timer:new(myTimer);
        
--]]
SW_C_Timer = {
        -- epoch time at init
        epochInit = time(),
        -- system up time at init
        upTimeInit = GetTime(),
        
        new = function (self, o)
                o = o or {};
                setmetatable(o, self);
                self.__index = self;
                
                if o.epochTS ~= nil then
                        o.uTS = (o.epochTS + o.msO) - self.epochInit ;
                else
                        self.setToNow(o);
                end
                return o;
        end,
                
        setToNow = function(self)
                self.epochTS = time();
                self.uTS = GetTime() - self.upTimeInit;
                -- store the millisecond offset
                self.msO = self.uTS - (self.epochTS - self.epochInit);
        end,
        
        -- now return value is not to be used cross session (don't save it)
        now = function(self)
                return GetTime() - self.upTimeInit;
        end,
        
        elapsed = function(self)
                return self.msRound((GetTime() - self.upTimeInit) - self.uTS);  
        end,
        
        -- one must be a timer object, the other value may be a number
        -- only numbers recieved through :now() make sense
        __sub = function(lh, rh)
                if type(rh) == "number" then
                        return lh.uTS - rh;
                elseif type(lh) == "number" then
                        return lh - rh.uTS;
                else
                        return lh.msRound(lh.uTS - rh.uTS);
                end
        end,
        
        msRound = function(val)
                return math.floor((val) * 1000 + 0.5)/1000;
        end,
        absDiff = function(self, rh)
                local ret = self - rh;
                if ret < 0 then ret = -ret; end
                return ret; 
        end,
        
        -- seconds since startup
        SSS = function(self)
                return GetTime() - self.upTimeInit;
        end,
        
        dump = function(self)
                SW_DumpTable(self);
        end,
}
--------- My fun function so don't complain
SW_RND_Strings = { 
        ["CWATER"] = {
                "pinkelt in eine Flasche...",
                "erleichtert sich.",
                "machts euch in Kirschgeschmack.",
                "denkt 'Wasser, ja Wasser wollte Ich schon immer machen.'",
                "macht euch ein POWER drink.",
                "ahhh, besser!",
                "sammelt seine Tr\195\164nen in einer Flasche",
                "macht noch mehr Blubberwasser.",
                "sagt euch da\195\159 Er kein Bier herbeizaubern kann.",
                "machts euch in Pfirsichgeschmack",
                "zieht die Nase hoch...",
                "kriegt ein mulmiges Gefuehl im Magen.",
        },
        ["CBREAD"] = {
                "backe backe BROT!",
                "schmei\195\159t euch Brot an den Kopf!",
                "hat einen eigenartigen Gesichtsausdruck.",
                "PLOP!",
                "transmutiert Luft zu Brot.",
                "sucht sich ein B\195\164ckermeister.",
                
        },
};

function SW_GetRndString(baseIndex)
        if SW_RND_Strings[baseIndex] == nil then return; end
        local index = math.random(table.getn(SW_RND_Strings[baseIndex]));
        SendChatMessage(SW_RND_Strings[baseIndex][index], "EMOTE");
end
-------------------------- Dump Functions mostly for dev --------------------

function SW_printStr(str, toChannelNR)
        local chNR =1;
        if SW_DEV_INWOW then
                if toChannelNR ~= nil then chNR = toChannelNR; end
                local con = getglobal("SW_FrameConsole_Text"..chNR.."_MsgFrame");
                if con ~= nil then
                        if str == nil then
                                con:AddMessage("NIL");
                        elseif type(str) == "boolean" then
                                local v2 = "Bool:false";
                                if str then
                                        v2 = "Bool:true";
                                end
                                SW_printStr (v2);
                        else
                                con:AddMessage(str);
                        end
                        
                        --con:ScrollToBottom();
                end
        else
                print(str);
        end
end

function SW_DumpKeys(table)
        if table ==nil then return; end
        if type(table) ~= "table" then return; end
        SW_printStr("-- KEYS -- ");
        for k, v in pairs (table) do 
                SW_printStr(k);
                
        end
end
function SW_DumpTable(table, ds, ch, hideKey)
        if ch == nil then ch = 1; end
        if table ==nil then return "table is nil"; end
        if ds == nil then 
                ds="" 
                SW_printStr("----------------------");
        end
        
        for k, v in pairs (table) do 
                if type(v) ~= "table" then
                        if v == nil then
                                if hideKey then
                                        SW_printStr (ds.."NIL", ch);
                                else
                                        SW_printStr (ds.."["..k.."]=NIL", ch);
                                end
                        elseif type(v) == "boolean" then
                                local v2 = "Bool:false";
                                if v then
                                        v2 = "Bool:true";
                                end
                                if hideKey then
                                        SW_printStr (ds..v2, ch);
                                else
                                        SW_printStr (ds.."["..k.."]="..v2, ch);
                                end
                        elseif type(v) == "function" then
                                if hideKey then
                                        SW_printStr (ds.."function", ch);
                                else
                                        SW_printStr (ds.."["..k.."]=function", ch);
                                end
                        else
                                if hideKey then
                                        SW_printStr (ds..v, ch);
                                else
                                        SW_printStr (ds.."["..k.."]="..v, ch);
                                end
                        end
                else
                
                        if not hideKey then
                                SW_printStr (ds.."["..k.."]=", ch);
                        end 
                        SW_DumpTable(v, ds.."       ");
                end
                
        end

end

function SW_DumpRegs()
        for k,v in pairs (SW_RegEx_Lookup) do
                if v["r"] == nil then
                        SW_printStr(k.."  EMPTY <- No global found with this name");
                else
                        SW_printStr(k.." "..v["r"]);
                end
                
        end
end
function SW_DumpResultList(...)
        local i = 1;
        local ret = "";
        while arg[i] ~= nil do
                ret = ret..arg[i].." "; 
                i = i + 1;
        end
        SW_printStr(ret);
end

function SW_DumpFMAsVar()
        SW_printStr("SW_DefaultMap={");
        for k, v in pairs (SW_DEV_FINDMATCH) do 
                SW_printStr("\t[\""..k.."\"] = {") ;
                for e, _ in pairs (v) do
                        -- dont add VSENVIRONMENTALDAMAGE
                        if string.sub(e,1,string.len("VSENVIRONMENTALDAMAGE"))~="VSENVIRONMENTALDAMAGE" then
                                SW_printStr("\t\t\""..e.."\",") ;
                        end

                        
                end
                SW_printStr("\t},") ;
        end
        SW_printStr("}");
end

Generated by GNU Enscript 1.6.5.90.