vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--[[

        HunterPetSkills: Search an in-game database to find where the pet
                skill and rank you need is located. Type << /petskills >> for
                a list of commands. copyright 2005 by Jake Bolton (ninmonkey) ninmonkeys@gmail.com
        
        Author: Jake Bolton (ninmonkey) email: ninmonkeys@gmail.com
                (if you have any problems, or features you want added, email me)
                
        Usage:
                Type << /sk >> or << /petskills >> or << /hunterpetskills >>
                for a list of commands
                
        Examples:
                see the "HunterPetSkills_readme.txt" for examples and more
                details on the mod usage

        LastUpdate: 6/28/2005 (this isn't that accurate :P )

        Thanks To:
                -John Ruben     (Tulas), for helping improve the pet skill
                        descriptions, and ideas for the mod in general.

                -I started with base info from The Good Intentions Guild
                ( http://www.goodintentionsguild.info ), then updated my
                database with current info from hunters (ie: tulas) You can
                view the guilds pet page at: http://www.goodintentionsguild.info/hunters.html

        Version 0.2.1 (not made yet)
                
                -(todo) see todo for a list of what to do (ie: focus amount)
                -(todo) find levels for (?) beasts
                -(todo) change error when bad input for /sk <skill> <rank> <zone>
                        -if zone does not match, output zone not found
                        -allow partial zone name match


        Version 0.2.0 (Current Version)
                -updated TOC to version 1500 for blizzard patch
                -added skill sprint
                -added skill dive
                -"skill" is optional, meaning you can type "/sk bite 1" or "/sk skill bite 1"
                -added ingame help to show sprint/dive are availible skills
                -updated readme
                -help output shows "skill" is optional by using brackets: "[skill]", as well as in the readme

        Version 0.1.3
                -updated for new blizz patch was 4216 for 1300

        Version 0.1.2:
                -updated interface number for blizzard's patch
                -colored help
                -cleaned up and shortened skill output
                -skill output is colored
                
        Version 0.1.1:
                -new command shortcut /sk (/hunterpetskills, /petskills, or /sk all work)
                -strings changed in bite, claw, and cower
        
        (for full changelog, view readme)

        todo:
                -append to skill description focus etc? Or a special command
                        that lists all skills with the tooltips?
                        
                        -skill list to append:
                                -bite: 35 focus, instant, 10 seconds cooldown,
                                        range 5 yards
                                -claw: 25 focus, instant, 5 yard range
                                -dash: 20 focus, instant, 30 seconds cooldown
                                -dive: 20 focus, instant, 30 seconds cooldown
                                -growl:15 focus, instant, 5 seconds cooldown,
                                        5 yard range

                        -append who can learn what:

                                -bite: cannot be learned by:
                                        -crabs, scorpids, or owls

                                -claw: cannot be learned by:
                                        -bats, boars, crocolisks, gorillas,
                                                hyenas, spiders, tall striders,
                                                turtles, wind serpents, or
                                                wolves/worgs
                                
                                -cower: can be learned by all
                                -growl: can be learned by all
                                
                                -dash: cannot be learned by:
                                        -bears, crabs, crocolisks, gorillas,
                                                raptors, scorpids, spiders,
                                                turtles, or any flying beast

                                -dive: cannot be learned by:
                                        -any land-based beast

                -fix /sk <skill_name> <skill_rank>

                -pet families
                        -petFamilyArray
                                -1 = claw, 2 = bite, 3 = both
                -show which families can/cannot learn claw/bite/sprint/dive
                        -possible search, else output families
                                -example:
                                -cat: skill1, skill2, skill3
                                -turtle: skill1, skill2
                                -raptor: skill1, skill2, skill3, skill4

                -if search without zone name, first do a search with current zone name,
                        if no results, then search all zones (save user time and typing)

                -disable if not hunter
                        -- set pet arrays to nil?
                        -- don't register events?

                        -- do anything else?

                        
        notes:
                -ToQuit
                -- local playerClass = UnitClass("player"); -- mage, warrior, etc..
                
                -for pet stats
                -- curXP, nextXP = GetPetExperience();
                -- creatureFamily = UnitCreatureFamily(unit);
                        -- returns creature family, eg: bear, cat, crab, etc...                                 

Coming soon:    
        -View pet families
        -View pet families that can only learn claw
        -View pet families that can only learn bite
        -View pet families that can learn all skills    


]]

-----------------------------------
-- variables
-----------------------------------

-- mod version
HUNTERPETSKILLS_MOD_VERSION = "0.2.0";
HUNTERPETSKILLS_MOD_NAME = "|cffffff00HunterPetSkills "..HUNTERPETSKILLS_MOD_VERSION.."|r";

-- console command list
HUNTERPETSKILLS_COMMANDS = { help="help", skill="skill" };

HUNTERPETSKILLS_COLOR = { zone="447cbf", help="447cbf", helpheader="099779" };

-- displayed at /sk help        -- "HunterPetSkills Help:",
HUNTERPETSKILLS_HELP_TEXT = {
        HUNTERPETSKILLS_MOD_NAME.." Help:",
        HUNTERPETSKILLS_COMMANDS["help"]..": Shows this help file.",
        "["..HUNTERPETSKILLS_COMMANDS["skill"].."] <skill_name> <skill_rank> [<zone>]: Lists beasts that have <skill_name>(bite|claw|growl|cower|dash|dive) with rank <skill_rank>(0-8). Optionally can try to search a zone.",
};

-- skill arrays

-- bite: rank = description, pet level, locations {zone_name=beast_list,
--      zone_name2=beast_list2,..}



local HUNTERPETSKILLS_DATA_BITE = {
        [1] = {"Bite the enemy, causing 9 to 11 damage", 1, locations = {
                DunMorogh="Snow Tracker Wolf (5-7), Winter Wolf (6-8)",
                Durotar="Dreadmaw Crocolisk (9-11)",
                Mulgore="Prairie Wolf (5-6)",
                Teldrassil="Webwood Venomfang (7-8)"
        }},
        
        [2] = {"Bite the enemy, causing 16 to 18 damage", 8, locations = {
                Barrens="Echeyakee (16), Savannah Huntress(12-13), Savannah Prowler(14-15), Oasis Snapjaw (15-16)",
                DunMorogh="Starving Winter Wolf (8-9), Timber (10)",
                ElwynnForest="Mother Fang (10), Prowler (9-10)",
                LochModan="Forest Lurker (13-14), Loch Crocolisk (14-15)",
                Mulgore="Prairie Wolf Alpha (9-10)",
                RedridgeMountains="Tarantula (15-16)",
                Teldrassil="Giant Webwood Spider (10-11), Lady Sathrah (12), Webwood Silkspinner (8-9)",
                TirisfalGlades="Worg (10-11)",
                Westfall="Coyote Packleader (11-12)"
        }},
        
        [3] = {"Bite the enemy, causing 24 to 28 damage", 16, locations = {
                Ashenvale="Ghost Paw Runner (19-20)",
                Duskwood="Green Recluse (21)",
                HillsbradFoothills="Forest Moss Creeper (20-21)",
                LochModan="Wood Lurker (17-18)",
                Redridge="Greater Tarantula (19-20)",
                SilverpineForest="Bloodsnout Worg (16-17)",
                StonetalonMountains="Besseleth (21+)",
                WailingCaverns="Deviate Crocolisk (18+-19+)"    
        }},
        
        [4] = {"Bite the enemy, causing 31 to 37 damage", 24, locations = {
                Ashenvale="Ghostpaw Alpha (27-28)",
                BlackfathomDeep="Ghamoo-Ra(25+)",
                Duskwood="Black Mastiff (25-26), Black Ravager (24-25), Naraxis(27)",
                HillsbradFoothills="Giant Moss Creeper (24), Elder Moss Creeper (27), Snapjaw (30)",
                Wetlands="Giant Wetlands Crocolisk(25-26)"
        }},
        
        [5] = {"Bite the enemy, causing 40 to 48 damage", 32, locations = {
                ArathiHighlands="Giant Plains Creeper(35-36), Plains Creeper (32-33)",
                Badlands="Crag Coyote (35-36)",
                DustwallowMarsh="Darkfang Lurker (36-37), Drywallow Crocolisk (35-36), Mudrock Tortoise (36-37)",
                ThousandNeedles="Sparkleshell Snapper (34-35)"  
        }},
        
        [6] = {"Bite the enemy, causing 49 to 59 damage", 40, locations = {
                Felwood="Felpaw Wolf (47-48)",
                Feralas="Longtooth Runner (40-41), Snarler (42), Wolves (41, 47)",
                Hinterlands="Witherbark Broodguard (44-45)",
                SwampOfSorrows="Deathstrike Tarantula (40-41)"  
        }},
        
        [7] = {"Bite the enemy, causing 66 to 80 damage", 48, locations = {
                Felwood="Felpaw Ravager (51-52)",
                Hinterlands="Saltwater Snapjaw (49-50), Vilebranch Raiding Wolf (51+-52+)",
                Stormwind="Sewer Beast (50+)",
                WesternPlagueland="Diseased Wolf(53-54), Plague Lurker (54-55)"
        }},
        
        [8] = {"Bite the enemy, causing 81 to 99 damage", 56, locations = {
                BlackrockSpires="Bloodaxe Warg (56-57) - spawns near Halycon"
        }},

};

-- claw: rank = description, pet level, locations {zone_name=beast_list,
--      zone_name2=beast_list2,..}

local HUNTERPETSKILLS_DATA_CLAW = {
        [1] = {"Claw the enemy, causing 4 to 6 damage", 1, locations = {
                DunMorogh="Ice Claw Bear (7-8)",
                Durotar="Pygmy Surf Crawler (5-6), Scorpid Workers (3)",
                Teldrassil="Strigid Owl (5-6)"
        }},
        
        [2] = {"Claw the enemy, causing 8 to 12 damage", 8, locations = {
                Darkshore="Thistle Bear (11-12)",
                DunMorogh="Bjarn (12), Mangeclaw (11)",
                Durotar="Death Flayer (11), Encrusted Surf Crawler (9-10), Venomtail Scorpid (9-10)",
                ElwynnForest="Young Forest Bear (8-9)",
                SilverpineForest="Giant Grizzled Bear (12-13)",
                Teldrassil="Strigid Hunter (8-9)"
        }},
        
        [3] = {"Claw the enemy, causing 12 to 16 damage", 16, locations = {
                Ashenvale="Ashenvale Bear (21-22), Clattering Crawler (19-20)",
                Darkshore="Den Mother (19)",
                HillsbradFoothills="Gray Bear (21-22)",
                LochModan="Black Bear Patriarch (16-17), Ol' Sooty (20+)",
                Westfall="Shore Crawler (17-18)"        
        }},
        
        [4] = {"Claw the enemy, causing 16 to 22 damage", 24, locations = {
                Ashenvale="Elder Ashenvale Bear (25-26)",
                Desolace="Scorpashi Snapper (30-31)",
                ThousandNeedles="Scorpid Reaver(31-32)"
        }},
        
        [5] = {"Claw the enemy, causing 21 to 29 damage", 32, locations = {
                Desolace="Scorpashi Lasher (34-35)"
        }},
        
        [6] = {"Claw the enemy, causing 26 to 36 damage", 40, locations = {
                Feralas="Ironfur Bear (41-42)",
                SwampOfSorrows="Silt Crawler (40-41)",
                Tanaris="Scorpid Hunter (40-41)"
        }},
        
        [7] = {"Claw the enemy, causing 35 to 49 damage", 48, locations = {
                BurningSteppes="Deathlash Scorpid (54-55)",
                Felwood="Angerclaw Mauler (49-50), Ironbeak Hunter (50-51)",
                Feralas="Ironfur Patriarch (48-49)",
                Winterspring="Shardtooth Bear (53-55), Winterspring Owl (54-56)"
        }},
        
        [8] = {"Claw the enemy, causing 43 to 59 damage", 56, locations = {
                WesternPlaguelands="Diseased Grizzly (55-56)",
                Winterspring="Elder Shardtooth (57-58), Winterspring Screecher (57-59)"         
        }}
};

-- cower: rank = pet level, locations {zone_name=beast_list,
--      zone_name2=beast_list2,..}

local HUNTERPETSKILLS_DATA_COWER = {
        [1] = {5, locations = {
                Barrens="Elder Plainstrider (8-9), Fleeting Plainstrider (12-13)",
                Darkshore="Foreststrider Fledging (11-13), Moonstalker Runt (10-11)",
                DunMorogh="Juvenile Snow Leopard (5-6)",
                Durotar="Durotar Tiger (7-8)",
                Mulgore="Elder Plainstrider (8-9), Flatland Cougar (7-8), Mazzranache (9)",
                Teldrassil="Mangy Nightsaber (2), Nightsaber (5-6)",
                TirisfalGlades="Greater Duskbat (6-7)"
        }},
        
        [2] = {15, locations = {
                Barrens="Ornery Plainstrider (16-17), Savannah Patriarch (15-16)",
                Darkshore="Giant Foreststrider (17-19), Moonstalker Sire (17-18)",
                HillsbradFoothills="Starving Mountain Lion (23-24)",
                StonetalonMountains="Panther, Twilight Runner (23-24)"
        }},
        
        [3] = {25, locations = {
                ArathiHighlands="Highland Strider (30-31)",
                HillsbradFoothills="Feral Mountain Lion (27-28)",
                RazorfenKraul="Blind Hunter (32), Kraul Bat (30+-31+)",
                StranglethornVale="Stranglethorn Tiger (32-33), Young Stranglethorn Panther (30-31), Young Stranglethorn Tiger (30-31)",
                ThousandNeedles="Crag Stalker (25-26)"  
        }},
        
        [4] = {35, locations = {
                Badlands="Ridge Huntress (38-39), Ridge Stalker (36-37)"        
        }},
        
        [5] = {45, locations = {
                EasternPlaguelands="Noxious Plaguebat (54-56)",
                StranglethornVale="Jaguero Stalker (50)"
        }},
        
        [6] = {55, locations = {
                EasternPlaguelands="Monstrous Plaguebat (57-58)",
                Winterspring="Frostsaber Cub (55-56)"   
        }},
};


-- dash: rank = description, pet level, locations {zone_name=beast_list,
--      zone_name2=beast_list2,..}

local HUNTERPETSKILLS_DATA_DASH = {
        [1] = {"Increases movement speed by 40 for 15 seconds", 30,
                locations = {
                Badlands="Crag Coyote (36), Elder Crag Wolf (?)",
                Desolace="Magram Bonepaw (37-38)",
                StranglethornVale="Stranglethorn Tigers (32-33)",
                SwampOfSorrows="Swamp Jaguar (37)"
        }},

        [2] = {"Increases movement speed by 60 for 15 seconds", 40,
                locations = {
                Badlands="Broken Tooth (37), Ridge Stalker Patriarch (?)",
                BlastedLands="Ashmane Boar (48)",
                Feralas="Longtooth Runner (40-41)",
                Hinterlands="Old Cliff Jumper (42), Silvermane Stalker (48)",
                StranglethornVale="BhagTera (elite 43), Elder Shadowmaw Panther (41-43)",
                Tanaris="Blisterpaw Hyena (41-42), Starving Blisterpaw (42)"
        }},

        [3] = {"Increases movement speed by 80 for 15 seconds", 50,
                locations = {
                BlackrockSpires="Bloodaxe Worg (56-57)",
                BlastedLands="Grunter (50), Hyena Ravage (elite (?))",
                BlackrockSpires="Blackrock Worg (54-55)",
                Hinterlands="Vilebranch Raiding Wolf (50-51)",
                Winterspring="Frostsaber Huntress (58-59), Frostsaber Stalker (60), RakShiri (rare blue frostsaber (?))"
        }},
};



-- dive: rank = description, pet level, locations {zone_name=beast_list,
--      zone_name2=beast_list2,..}

local HUNTERPETSKILLS_DATA_DIVE = {
        [1] = {"Increases movement speed by 40 for 15 seconds", 30,
                locations = {
                ArathiHighlands="Mesa Buzzard (35), Young Mesa Buzzard (31)",
                RazorfenKraul="Razorfen Kraul Bat (31)",
                Desolace="Dread Flyer (36-37)"
        }},

        [2] = {"Increases movement speed by 60 for 15 seconds", 40,
                locations = {
                Felwood="Ironbeak Owls (48-49)",
                Feralas="Rogue Vale Screecher (46), Wind Serpent (44)",
                Tanaris="Roc (42-43)"
        }},

        [3] = {"Increases movement speed by 80 for 15 seconds", 50,
                locations = {
                Badlands="Zaricotl (55)",
                BlastedLands="Spiteflayer (elite 52)",
                EasternPlaguelands="Plaguebat (54)",
                Felwood="Ironbeak Hunter (51), Ironbeak Screecher (53)",
                Winterspring="Winterspring Owl (55), Winterspring Screecher (59)"
        }},
};


-- growl: rank = pet level, learned from (and requirements), cost to buy

local HUNTERPETSKILLS_DATA_GROWL = {
        [1] = { 1, learn="Innate knowledge", cost="free" },
        [2] = { 10, learn="Innate knowledge", cost="free" },
        [3] = { 20, learn="Learned fom Pet Trainers, requires level 20", cost="30sp" },
        [4] = { 30, learn="Learned fom Pet Trainers, requires level 30, Growl 3", cost="1gp" },
        [5] = { 40, learn="Learned fom Pet Trainers, requires level 40, Growl 4", cost="2gp" },
        [6] = { 50, learn="Learned fom Pet Trainers, requires level 50, Growl 5", cost="4gp 70sp" },
        [7] = { 60, learn="Learned fom Pet Trainers, requires level 60, Growl 6", cost="5gp 90sp" }
};

-- const strings
local HUNTERPETSKILLS_DESC_COWER = "Cower, causing no damage but lowering your threat, making the enemy less likey to attack you";
local HUNTERPETSKILLS_DESC_GROWL = "Taunt the target, increasing the likelihood the creature will focus atacks on you";

-----------------------------------
-- local functions
-----------------------------------

local function print_error(msg)
    DEFAULT_CHAT_FRAME:AddMessage(msg.." Type /petskills or /sk help for a list of commands.");
end

local function print_msg(msg)
        DEFAULT_CHAT_FRAME:AddMessage(msg);
end

local function print_debug(msg)
        DEFAULT_CHAT_FRAME:AddMessage("Debug: "..msg);
end

local function HelpColor()

        -- version:     v0.2
        -- last update: 2005


        --== notes ==--
        -- changed: regex is now "^(.-):(.*)$" (using non-greedy mode for first capture)
                
        -- output colorized help (keeps help strings clean of color codes)
        
        -- if first line, either color, or leave plain
        -- all other lines, start with color blue, end before character ":"
        -- color start: |cff, color end: |r
        
        local index;
    local value;
    for index, value in HUNTERPETSKILLS_HELP_TEXT do
        local sText;
        
        if(index == 1) then     
                        
                        -- header                       
                sText = "|cff"..HUNTERPETSKILLS_COLOR["helpheader"]..value.."|r";
                print_msg(sText);                               
        else            
                
                        --color normally                
                local sStart, sEnd, sCmd, sDesc = string.find(value, "^(.-):(.*)$");
                sText = "|cff"..HUNTERPETSKILLS_COLOR["help"]..sCmd.."|r:"..sDesc;
                if( (sCmd == nil) or (sDesc == nil) ) then
                        -- if error in search, print non-colored string
                        print_msg(value);
                end             
                -- print colored string
                print_msg(sText);
        end
    end
end

-----------------------------------
-- local command line functions
-----------------------------------

local function HunterPetSkills_PrintSkillList(ZoneName, BeastList)
        --output skill list so print code only needs to be changed in one place
        
        -- in color print: print_msg("<"..ZoneName.."> "..BeastList);
        print_msg("|cff"..HUNTERPETSKILLS_COLOR["zone"].."<"..ZoneName..">|r "..BeastList);

end

local function HunterPetSkills_Skill(SkillName, SkillRank, SkillZone)
        
        -- Search for the skill, format:
        -- description, pet level, locations {zone_name=beast_list, zone_name2=beast_list2,..}
        
        local index;
        local value;
        local bFilter = false;
        
        -- if not nil
        if( (SkillRank == nil) or (SkillName == nil) ) then
            print_error("Error: Skill Name and Rank required!");
            return;
        end
        
        -- make SkillName case-insensitive for compare
        SkillName = string.lower(SkillName);
        -- convert rank to number       
        SkillRank = tonumber(SkillRank);
        
        -- output skill name, rank, and zone
        if( SkillZone and (SkillZone ~= "" )) then
                -- lower and print
                SkillZone = string.lower(SkillZone);            
                print_msg(string.format("Skill: %s (Rank %i) Zone: %s", SkillName, SkillRank, SkillZone));
                
                -- get ready for filter, remove spaces                          
                bFilter = true;
                SkillZone = string.gsub(SkillZone, "%s+", "");
        else
                -- no zone given, print none
                print_msg(string.format("Skill: %s (Rank %i) Zone: All", SkillName, SkillRank));
        end     
        
        if( SkillName == "bite" ) then
                
                -- check if inbounds
                if( tonumber(SkillRank) <= table.getn(HUNTERPETSKILLS_DATA_BITE) ) then
                                                                
                        -- print desc, pet level
                        print_msg("Description: "..HUNTERPETSKILLS_DATA_BITE[SkillRank][1]);
                        print_msg("Requires pet level: "..HUNTERPETSKILLS_DATA_BITE[SkillRank][2]);
                        
                        -- print locations {zone_name=beast_list, zone_name2=beast_list2,..}
                        local ZoneName;
                local BeastList;
                for ZoneName, BeastList in HUNTERPETSKILLS_DATA_BITE[SkillRank]["locations"] do
                        
                                -- if filter, else regular
                                if(bFilter) then
                                if(string.lower(ZoneName) == SkillZone) then
                                        -- filtering, so make sure it matches
                                                -- (SkillZone was string.lower()'ed above)

                                                -- print filtered zone and beast list
                                HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                                end
                        else
                        -- no filter, print all zones
                        HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                    end
                    
                end
                        
                else
                        print_error("Error, invalid rank!");
                end

        elseif( SkillName == "dash" ) then
        
                -- check if inbounds
                if( tonumber(SkillRank) <= table.getn(HUNTERPETSKILLS_DATA_DASH) ) then
                        
                        -- print desc, pet level
                        print_msg("Description: "..HUNTERPETSKILLS_DATA_DASH[SkillRank][1]);
                        print_msg("Requires Pet Level: "..HUNTERPETSKILLS_DATA_DASH[SkillRank][2]);
                        
                        -- print locations {zone_name=beast_list, zone_name2=beast_list2, ...}
                        local ZoneName;
                        local BeastList;
                        
                        -- for each zone, print beast list and color zone name
                        for ZoneName, BeastList in HUNTERPETSKILLS_DATA_DASH[SkillRank]["locations"] do
                                
                                -- if filter, else regular
                                if(bFilter) then
                                        if(string.lower(ZoneName) == SkillZone) then
                                                -- filtered, and made a match
                                                -- SkillZone was string.lower()'ed above

                                                HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                                        end
                                else
                                        -- no filter, print all zones
                                        HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                                end
                        end
                else
                        -- first if failed
                        print_error("Error, invalid rank!");
                end

        elseif( SkillName == "dive" ) then
        
                -- check if inbounds
                if( tonumber(SkillRank) <= table.getn(HUNTERPETSKILLS_DATA_DIVE) ) then
                        
                        -- print desc, pet level
                        print_msg("Description: "..HUNTERPETSKILLS_DATA_DIVE[SkillRank][1]);
                        print_msg("Requires Pet Level: "..HUNTERPETSKILLS_DATA_DIVE[SkillRank][2]);
                        
                        -- print locations {zone_name=beast_list, zone_name2=beast_list2, ...}
                        local ZoneName;
                        local BeastList;
                        
                        -- for each zone, print beast list and color zone name
                        for ZoneName, BeastList in HUNTERPETSKILLS_DATA_DIVE[SkillRank]["locations"] do
                                
                                -- if filter, else regular
                                if(bFilter) then
                                        if(string.lower(ZoneName) == SkillZone) then
                                                -- filtered, and made a match
                                                -- SkillZone was string.lower()'ed above

                                                HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                                        end
                                else
                                        -- no filter, print all zones
                                        HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                                end
                        end
                else
                        -- first if failed
                        print_error("Error, invalid rank!");
                end
        
        elseif( SkillName == "claw" ) then

                -- check if inbounds
                if( tonumber(SkillRank) <= table.getn(HUNTERPETSKILLS_DATA_CLAW) ) then
                                                                
                        -- print desc, pet level
                        print_msg("Description: "..HUNTERPETSKILLS_DATA_CLAW[SkillRank][1]);
                        print_msg("Requires pet level: "..HUNTERPETSKILLS_DATA_CLAW[SkillRank][2]);
                        
                        -- print locations {zone_name=beast_list, zone_name2=beast_list2,..}
                        local ZoneName;
                local BeastList;
                for ZoneName, BeastList in HUNTERPETSKILLS_DATA_CLAW[SkillRank]["locations"] do

                                -- if filter, else regular
                                if(bFilter) then
                                if(string.lower(ZoneName) == SkillZone) then
                                        -- filtering, so make sure it matches
                                                -- (SkillZone was string.lower()'ed above)

                                                -- print filtered zone and beast list
                                HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                                end
                        else
                        -- no filter, print all zones
                        HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                    end

                end
                        
                else
                        print_error("Error, invalid rank!");
                end
                
        elseif( SkillName == "cower" ) then
                -- cower: pet level, locations {zone_name=beast_list, zone_name2=beast_list2,..}
                
                -- check if inbounds
                if( tonumber(SkillRank) <= table.getn(HUNTERPETSKILLS_DATA_COWER) ) then
                                                                
                        -- print desc, pet level
                        print_msg("Description: "..HUNTERPETSKILLS_DESC_COWER);
                        print_msg("Requires pet level: "..HUNTERPETSKILLS_DATA_COWER[SkillRank][1]);
                        
                        -- print locations {zone_name=beast_list, zone_name2=beast_list2,..}
                        local ZoneName;
                local BeastList;
                for ZoneName, BeastList in HUNTERPETSKILLS_DATA_COWER[SkillRank]["locations"] do
                
                                -- if filter, else regular
                                if(bFilter) then
                                if(string.lower(ZoneName) == SkillZone) then
                                        -- filtering, so make sure it matches
                                                -- (SkillZone was string.lower()'ed above)

                                                -- print filtered zone and beast list
                                HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                                end
                        else
                                -- no filter, print all zones
                        HunterPetSkills_PrintSkillList(ZoneName, BeastList);
                    end         
                end
                        
                else
                        print_error("Error, invalid rank!");
                end
                
        elseif( SkillName == "growl" ) then
                -- growl: pet level, learned from (and requires), cost
                
                -- check if inbounds
                if( tonumber(SkillRank) <= table.getn(HUNTERPETSKILLS_DATA_GROWL) ) then
                                                                
                        -- print desc, pet level
                        print_msg("Description: "..HUNTERPETSKILLS_DESC_GROWL);
                        print_msg("Requires pet level: "..HUNTERPETSKILLS_DATA_GROWL[SkillRank][1]);
                        
                        -- print learned from, requires rank X, cost
                        print_msg("Trained: "..HUNTERPETSKILLS_DATA_GROWL[SkillRank]["learn"]);
                        print_msg("Cost: "..HUNTERPETSKILLS_DATA_GROWL[SkillRank]["cost"]);
                        
                else
                        print_error("Error, invalid rank!");
                end
                
        else
                -- invalid skill name
                print_error("Error: Invalid skill name!");
        end
        
end


-----------------------------------
-- slash commands
-----------------------------------

function HunterPetSkills_SlashCommandHandler(msg)

        if( msg ) then
                local command = string.lower(msg);

                if( command == "" or command == HUNTERPETSKILLS_COMMANDS["help"] ) then

                -- print out help
                        HelpColor();

--[[
                -- old way that failed
                elseif( string.find(command, "^growl ") ) then
                        -- find a skill name not prefixed by skill
                        local sStart, sEnd, sRank, sZone = string.find(command,
                                 "^growl%s+(%d+)%s*([%a%d%s%p]*)%s*$");
                        HunterPetSkills_Skill("growl", sRank, sZone);
]]

                -- growl
                elseif( string.find(command, "^growl%s+(%d+)%s*([%a%d%s%p]*)%s*$") ) then
                        -- found growl without "skill" in the command
                        local sStart, sEnd, sRank, sZone = string.find(command,
                                "^growl%s+(%d+)%s*([%a%d%s%p]*)%s*$");
                        HunterPetSkills_Skill("growl", sRank, sZone);

                -- claw
                elseif( string.find(command, "^claw%s+(%d+)%s*([%a%d%s%p]*)%s*$") ) then
                        -- found claw without "skill" in the command
                        local sStart, sEnd, sRank, sZone = string.find(command,
                                "^claw%s+(%d+)%s*([%a%d%s%p]*)%s*$");
                        HunterPetSkills_Skill("claw", sRank, sZone);
                
                -- bite
                elseif( string.find(command, "^bite%s+(%d+)%s*([%a%d%s%p]*)%s*$") ) then
                        -- found bite without "skill" in the command
                        local sStart, sEnd, sRank, sZone = string.find(command,
                                "^bite%s+(%d+)%s*([%a%d%s%p]*)%s*$");
                        HunterPetSkills_Skill("bite", sRank, sZone);

                -- dash
                elseif( string.find(command, "^dash%s+(%d+)%s*([%a%d%s%p]*)%s*$") ) then
                        -- found dash without "skill" in the command
                        local sStart, sEnd, sRank, sZone = string.find(command,
                                "^dash%s+(%d+)%s*([%a%d%s%p]*)%s*$");
                        HunterPetSkills_Skill("dash", sRank, sZone);
                
                -- dive
                elseif( string.find(command, "^dive%s+(%d+)%s*([%a%d%s%p]*)%s*$") ) then
                        -- found dive without "skill" in the command
                        local sStart, sEnd, sRank, sZone = string.find(command,
                                "^dive%s+(%d+)%s*([%a%d%s%p]*)%s*$");
                        HunterPetSkills_Skill("dive", sRank, sZone);


                -- cower
                elseif( string.find(command, "^cower%s+(%d+)%s*([%a%d%s%p]*)%s*$") ) then
                        -- found cower without "skill" in the command
                        local sStart, sEnd, sRank, sZone = string.find(command,
                                "^cower%s+(%d+)%s*([%a%d%s%p]*)%s*$");
                        HunterPetSkills_Skill("cower", sRank, sZone);

                -- else they used "/sk skill <SkillName> <Rank> [<Zone>]
                elseif( string.find(command, "^"..HUNTERPETSKILLS_COMMANDS["skill"].." ") ) then

                        -- search for a skill
                                -- does %d equal [0-9], and does [%a%d] equal [%w] ?
                                -- %a = all letters
                                -- %d = all digits
                                -- %p = all punctuation
                                -- %s = all space
                                -- %w = alphanumeric

                        local sStart, sEnd, sSkill, sRank, sZone = string.find(command,
                                "^"..HUNTERPETSKILLS_COMMANDS["skill"].."%s+(%a+)%s+(%d+)%s*([%a%d%s%p]*)%s*$");

                        -- print_debug(string.format("Skill: %s (Rank %s), [%s]", sSkill, sRank, sZone));
                        HunterPetSkills_Skill(sSkill, sRank, sZone);

                else
                        -- invalid flag/command
                        print_error("CommandHandler: "..msg..": command not found!");
                end
        else
                -- no msg
                print_error("HunterPetSkills: CommandHandler: No command given!");
        end
end



------------------------------------
-- OnFoo functions
------------------------------------

function HunterPetSkills_OnEvent()
        if( event == "VARIABLES_LOADED" ) then
      
        -- check if variables exist, if not create/set them             
        end
end

function HunterPetSkills_OnLoad()
  
  -- Register events  
  this:RegisterEvent("VARIABLES_LOADED");
     
  -- Register slash command
  SLASH_HUNTERPETSKILLS1 = "/hunterpetskills";
  SLASH_HUNTERPETSKILLS2 = "/petskills";
  SLASH_HUNTERPETSKILLS3 = "/sk";
  
  SlashCmdList["HUNTERPETSKILLS"] = function(msg)
      HunterPetSkills_SlashCommandHandler(msg);
  end  

  -- loaded okay so show loaded text
  -- show on defualt chat window
  if( DEFAULT_CHAT_FRAME ) then
      DEFAULT_CHAT_FRAME:AddMessage("ninmonkey's "..HUNTERPETSKILLS_MOD_NAME.." loaded!");
  end

  -- show pop-up text like an error
  UIErrorsFrame:AddMessage("ninmonkey's "..HUNTERPETSKILLS_MOD_NAME.." loaded!", 1.0, 1.0, 1.0, 1.0, UIERRORS_HOLD_TIME);
  
end