-- SkillDB.lua: interface to the characters' known skill database -- $Id: SkillDB.lua 462 2006-09-18 15:50:04Z jnmiller $ function RecipeRadar_SkillDB_Init() if (not RecipeRadar_SkillDB) then RecipeRadar_SkillDB = { } end if (not RecipeRadar_SkillDB[GetRealmName()]) then RecipeRadar_SkillDB[GetRealmName()] = { } end local db = RecipeRadar_SkillDB_GetPlayerProfessions() -- fishing doesn't get an auto-reset during the spellbook parsing if (not db[RRS("Fishing")] or not db[RRS("Fishing")].Recipes) then db[RRS("Fishing")] = { Rank = 0, Recipes = { } } end end -- This function safely initializes the player's personal skill database. -- If no player is supplied, the current player is assumed. function RecipeRadar_SkillDB_GetSafePlayerDB(player) if (not RecipeRadar_SkillDB) then RecipeRadar_SkillDB_Init() end if (not player) then player = UnitName("player") end local db = RecipeRadar_SkillDB[GetRealmName()] if (not db[player]) then db[player] = { } end if (not db[player].Team) then db[player].Team = UnitFactionGroup("player") end if (not db[player].Professions) then db[player].Professions = { } end if (not db[player].Factions) then db[player].Factions = { } end return db[player] end -- This is a safe function to retrieve the current character's team. function RecipeRadar_SkillDB_GetPlayerTeam(player) return RecipeRadar_SkillDB_GetSafePlayerDB(player).Team end -- This is a safe function to retrieve the current character's skills. function RecipeRadar_SkillDB_GetPlayerProfessions(player) return RecipeRadar_SkillDB_GetSafePlayerDB(player).Professions end -- This is a safe function to retrieve the current character's reputation. function RecipeRadar_SkillDB_GetPlayerFactions(player) return RecipeRadar_SkillDB_GetSafePlayerDB(player).Factions end -- Refreshes the DB for the current player and currently open skill window. -- prof_type is one of 'trade' or 'craft'. function RecipeRadar_SkillDB_Refresh(prof_type) local profs = RecipeRadar_SkillDB_GetPlayerProfessions() local prof_name, prof_rank, max_rank = RecipeRadar_SkillDB_GetProfInfo(prof_type) if (not prof_name) then -- Beast Training, for instance, will cause this return end if (not profs[prof_name]) then profs[prof_name] = { } end profs[prof_name].Rank = prof_rank profs[prof_name].Recipes = { } -- this line might help avoid the 0 count that I seem to get on -- some early invocations of this function? local dummy = RecipeRadar_SkillDB_GetRecipeCount(prof_type) -- iterate over each listed recipe in the currently open skill window for i = 1, RecipeRadar_SkillDB_GetRecipeCount(prof_type) do local recipe, hdr = RecipeRadar_SkillDB_GetRecipeInfo(prof_type, i) if (recipe and hdr ~= "header") then -- map craft window names to real recipe names local map = RecipeRadar_NameMap[GetLocale()] if (map and map[recipe]) then profs[prof_name].Recipes[recipe] = nil recipe = map[recipe] end -- if it's not a header, the character knows this recipe profs[prof_name].Recipes[recipe] = 1 end end RecipeRadar_SkillDB_HandleSpecialCase(profs, prof_name, max_rank) end -- Adds unlisted/implied "recipes" to the skill DB. function RecipeRadar_SkillDB_HandleSpecialCase(profs, prof_name, max_rank) if (prof_name == RRS("First Aid") and max_rank > 150) then -- Expert First Aid - Under Wraps local name = RecipeRadar_GetSafeItemInfo(16084) if (name ~= RRS("Uncached Recipe")) then profs[RRS("First Aid")].Recipes[name] = 1 end end if (prof_name == RRS("Fishing") and max_rank > 150) then -- Expert Fishing - The Bass and You local name = RecipeRadar_GetSafeItemInfo(16083) if (name ~= RRS("Uncached Recipe")) then profs[RRS("Fishing")].Recipes[name] = 1 end end if (prof_name == RRS("Cooking") and max_rank > 150) then -- Expert Cookbook local name = RecipeRadar_GetSafeItemInfo(16072) if (name ~= RRS("Uncached Recipe")) then profs[RRS("Cooking")].Recipes[name] = 1 end end end -- Quick function to retrieve a profession rank. function RecipeRadar_SkillDB_GetRank(prof) local prof_db = RecipeRadar_SkillDB_GetPlayerProfessions()[prof] if (not prof_db) then return 0 end return prof_db.Rank end -- Quick function to set a new profession rank. function RecipeRadar_SkillDB_SetRank(prof, rank) local prof_db = RecipeRadar_SkillDB_GetPlayerProfessions()[prof] if (not prof_db) then return end prof_db.Rank = tonumber(rank) RecipeRadar_FrameUpdate() end -- Boolean function to determine whether a player in the DB has the -- reputation necessary to learn the supplied recipe. function RecipeRadar_SkillDB_HasRep(player, recipe) if (not recipe.Faction or recipe.Faction == "") then return true end local factions = RecipeRadar_SkillDB_GetPlayerFactions(player) if (not factions[recipe.Faction]) then return false end return factions[recipe.Faction] >= recipe.Level end -- Boolean function to determine whether a player in the DB has the -- specialty necessary to learn the supplied recipe. function RecipeRadar_SkillDB_HasSpec(player, recipe) if (not recipe.Specialty or recipe.Specialty == "") then return true end local db = RecipeRadar_SkillDB_GetPlayerProfessions(player) if (not db[recipe.Type]) then return false end return recipe.Specialty == db[recipe.Type].Specialty end -- Debug function to clear some or all of the skill DB. function RecipeRadar_SkillDB_Clear(player) local hdr = "Clearing all known recipes" if (player ~= "") then hdr = hdr .. " for " .. player end RecipeRadar_Print(hdr .. ".") if (RecipeRadar_SkillDB[GetRealmName()][player]) then RecipeRadar_SkillDB[GetRealmName()][player] = { } else RecipeRadar_SkillDB[GetRealmName()] = { } end end -- Debug function to print the skill database. function RecipeRadar_SkillDB_Print(player) local hdr = "Printing all known recipes" if (player ~= "") then hdr = hdr .. " for " .. player end RecipeRadar_Print(hdr .. ".") for realm_name, player_table in RecipeRadar_SkillDB do RecipeRadar_Print(" Realm: " .. realm_name) for player_name, prof_table in player_table.Professions do if (player == "" or player == player_name) then RecipeRadar_Print(" Player: " .. player_name) for prof_name, recipe_table in prof_table do RecipeRadar_Print(" Skill: " .. prof_name .. " (Rank " .. recipe_table.Rank .. ")") if (recipe_table.Recipes) then for recipe_name, valid in recipe_table.Recipes do RecipeRadar_Print(" Recipe: " .. recipe_name) end end end end end end end ------------------------------------------------------------------------------ -- Abstractions to account for the difference between crafts and trade skills ------------------------------------------------------------------------------ function RecipeRadar_SkillDB_GetProfInfo(prof_type) if (prof_type == "trade") then return GetTradeSkillLine() elseif (prof_type == "craft") then return GetCraftDisplaySkillLine() end end function RecipeRadar_SkillDB_GetRecipeCount(prof_type) if (prof_type == "trade") then return GetNumTradeSkills() elseif (prof_type == "craft") then return GetNumCrafts() end return 0 end function RecipeRadar_SkillDB_GetRecipeInfo(prof_type, index) local name, hdr if (prof_type == "trade") then name, hdr = GetTradeSkillInfo(index) elseif (prof_type == "craft") then name, _, hdr = GetCraftInfo(index) end return name, hdr end ------------------------------------------------------------------------------ -- Functions to open/parse various frames to update skill info. ------------------------------------------------------------------------------ -- Attempts to open the spellbook and returns true if successful or false if -- the spellbook was already open. function RecipeRadar_SkillDB_ShowSpellbookFrame() local sbf = DF_SpellBookFrame or SpellBookFrame if (not sbf:IsVisible()) then ToggleSpellBook(BOOKTYPE_SPELL) return true end return false end -- Closes the spellbook if it's visible and need_close is true. function RecipeRadar_SkillDB_HideSpellbookFrame(need_close) local sbf = DF_SpellBookFrame or SpellBookFrame if (sbf:IsVisible() and need_close) then ToggleSpellBook(BOOKTYPE_SPELL) end end -- Opens the spellbook and finds profession windows to open in order -- to parse skill data from each. function RecipeRadar_SkillDB_ParseSpellbookFrame() local need_close = RecipeRadar_SkillDB_ShowSpellbookFrame() _, _, _, num_spells = GetSpellTabInfo(1) for i = 1, num_spells do local name = GetSpellName(i, BOOKTYPE_SPELL) if (not name) then return end -- open each of the player's crafting windows if (RecipeRadar_IsProfession(name) and name ~= RRS("Fishing")) then CastSpell(i, BOOKTYPE_SPELL) end -- check for trade skill specializations local spec_prof = RecipeRadar_IsProfessionSpecialty(name) if (spec_prof) then local profs = RecipeRadar_SkillDB_GetPlayerProfessions() if (not profs[spec_prof]) then profs[spec_prof] = { } end profs[spec_prof].Specialty = name end end CloseTradeSkill() CloseCraft() RecipeRadar_SkillDB_HideSpellbookFrame(need_close) end -- Opens the character window and sets it to the skill frame. function RecipeRadar_SkillDB_ShowSkillFrame() PanelTemplates_SetTab(CharacterFrame, getglobal("SkillFrame"):GetID()) ShowUIPanel(CharacterFrame) CharacterFrame_ShowSubFrame("SkillFrame") end -- Closes the character window. function RecipeRadar_SkillDB_HideSkillFrame() HideUIPanel(CharacterFrame) end -- Opens the skill frame and parses profession data from the display. -- Just checking for fishing rank right now, as getting only rank (without -- recipe data) could be misleading for other professions. function RecipeRadar_SkillDB_ParseSkillFrame() local profs = RecipeRadar_SkillDB_GetPlayerProfessions() RecipeRadar_SkillDB_ShowSkillFrame() for i = 1, GetNumSkillLines() do local name, hdr, _, rank, _, modifier, max_rank = GetSkillLineInfo(i) if (name == RRS("Fishing")) then if (not profs[name]) then profs[name] = { } end profs[name].Rank = rank RecipeRadar_SkillDB_HandleSpecialCase(profs, name, max_rank) end end RecipeRadar_SkillDB_HideSkillFrame() end -- Opens the character window and sets it to the reputation frame. function RecipeRadar_SkillDB_ShowReputationFrame() PanelTemplates_SetTab(CharacterFrame, getglobal("ReputationFrame"):GetID()) ShowUIPanel(CharacterFrame) CharacterFrame_ShowSubFrame("ReputationFrame") end -- Closes the character window. function RecipeRadar_SkillDB_HideReputationFrame() HideUIPanel(CharacterFrame) end -- Opens the reputation frame and parses data from the display. function RecipeRadar_SkillDB_ParseReputationFrame() local factions = RecipeRadar_SkillDB_GetPlayerFactions() RecipeRadar_SkillDB_ShowReputationFrame() for i = 1, GetNumFactions() do -- note that we're skipping collapsed headers local name, _, level = GetFactionInfo(i); if (RecipeRadar_IsKnownFaction(name)) then factions[name] = level end end RecipeRadar_SkillDB_HideReputationFrame() end