Update: to fix mouseover tooltips having the red "Requires [5 * tier] points in Y talents" and missing the green "Click to learn" text on talents that have been unlocked, you need to make another change in Wow.exe (using for example OllyDbg).For 3.3.5a, at the below address, change the +3 to something else. You can either go to the address directly, or search the file for all referenced strings and find "TOOLTIP_TALENT_TIER_POINTS" in the results (it's one of the WoW constants described here):Code: [Select]address: 006226E LEA EAX,[EAX+EAX+3]For example, if you change the points spent requirement from the default 5 (as in the above code) to 4, you change it to +2 in this code to fix mouseover tooltips:Code: [Select]address: 006226E LEA EAX,[EAX+EAX+2]Here's what the example looks like in game. It holds up for the later tiers too, showing "Requires 8 points spent in Affliction Talents" for the third tier:This has the side effect of also affecting hunter pet talent tooltips. Normally if you don't have tier 2 pet talents unlocked, mousing over a tier 2 talent would say "Requires 3 points in [pet type] talents", but with the given example this would read "2 points", even though it still requires 3 points in reality (unless you change it). What a headache.
address: 006226E LEA EAX,[EAX+EAX+3]
address: 006226E LEA EAX,[EAX+EAX+2]
StaticPopupDialogs["CONFIRM_LEARN_PREVIEW_TALENTS"] = { text = CONFIRM_LEARN_PREVIEW_TALENTS, button1 = YES, button2 = NO, OnAccept = function (self) LearnPreviewTalents(PlayerTalentFrame.pet); end, OnCancel = function (self) end, hideOnEscape = 1, timeout = 0, exclusive = 1,}UIPanelWindows["PlayerTalentFrame"] = { area = "left", pushable = 6, whileDead = 1 };-- global constantsGLYPH_TALENT_TAB = 4;-- speed referenceslocal next = next;local ipairs = ipairs;-- local datalocal specs = { ["spec1"] = { name = TALENT_SPEC_PRIMARY, talentGroup = 1, unit = "player", pet = false, tooltip = TALENT_SPEC_PRIMARY, portraitUnit = "player", defaultSpecTexture = "Interface\Icons\Ability_Marksmanship", hasGlyphs = true, glyphName = TALENT_SPEC_PRIMARY_GLYPH, }, ["spec2"] = { name = TALENT_SPEC_SECONDARY, talentGroup = 2, unit = "player", pet = false, tooltip = TALENT_SPEC_SECONDARY, portraitUnit = "player", defaultSpecTexture = "Interface\Icons\Ability_Marksmanship", hasGlyphs = true, glyphName = TALENT_SPEC_SECONDARY_GLYPH, }, ["petspec1"] = { name = TALENT_SPEC_PET_PRIMARY, talentGroup = 1, unit = "pet", tooltip = TALENT_SPEC_PET_PRIMARY, pet = true, portraitUnit = "pet", defaultSpecTexture = nil, hasGlyphs = false, glyphName = nil, },};local specTabs = { }; -- filled in by PlayerSpecTab_OnLoadlocal numSpecTabs = 0;local selectedSpec = nil;local activeSpec = nil;-- cache talent info so we can quickly display cool stuff like the number of points spent in each tablocal talentSpecInfoCache = { ["spec1"] = { }, ["spec2"] = { }, ["petspec1"] = { },};-- cache talent tab widths so we can resize tabs to fit for localizationlocal talentTabWidthCache = { };-- ACTIVESPEC_DISPLAYTYPE values:-- "BLUE", "GOLD_INSIDE", "GOLD_BACKGROUND"local ACTIVESPEC_DISPLAYTYPE = nil;-- SELECTEDSPEC_DISPLAYTYPE values:-- "BLUE", "GOLD_INSIDE", "PUSHED_OUT", "PUSHED_OUT_CHECKED"local SELECTEDSPEC_DISPLAYTYPE = "GOLD_INSIDE";local SELECTEDSPEC_OFFSETX;if ( SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT" or SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT_CHECKED" ) then SELECTEDSPEC_OFFSETX = 5;else SELECTEDSPEC_OFFSETX = 0;end-- PlayerTalentFramefunction PlayerTalentFrame_Toggle(pet, suggestedTalentGroup) local hidden; local talentTabSelected = PanelTemplates_GetSelectedTab(PlayerTalentFrame) ~= GLYPH_TALENT_TAB; if ( not PlayerTalentFrame:IsShown() ) then ShowUIPanel(PlayerTalentFrame); hidden = false; else local spec = selectedSpec and specs[selectedSpec]; if ( spec and talentTabSelected ) then -- if a talent tab is selected then toggle the frame off HideUIPanel(PlayerTalentFrame); hidden = true; else hidden = false; end end if ( not hidden ) then -- open the spec with the requested talent group (or the current talent group if the selected -- spec has one) if ( selectedSpec ) then local spec = specs[selectedSpec]; if ( spec.pet == pet ) then suggestedTalentGroup = spec.talentGroup; end end for _, index in ipairs(TALENT_SORT_ORDER) do local spec = specs[index]; if ( spec.pet == pet and spec.talentGroup == suggestedTalentGroup ) then PlayerSpecTab_OnClick(specTabs[index]); if ( not talentTabSelected ) then PlayerTalentTab_OnClick(_G["PlayerTalentFrameTab"..PlayerTalentTab_GetBestDefaultTab(index)]); end break; end end endendfunction PlayerTalentFrame_Open(pet, talentGroup) ShowUIPanel(PlayerTalentFrame); -- open the spec with the requested talent group for index, spec in next, specs do if ( spec.pet == pet and spec.talentGroup == talentGroup ) then PlayerSpecTab_OnClick(specTabs[index]); break; end endendfunction PlayerTalentFrame_ToggleGlyphFrame(suggestedTalentGroup) GlyphFrame_LoadUI(); if ( GlyphFrame ) then local hidden; if ( not PlayerTalentFrame:IsShown() ) thenentFrame); hidden = false; else local spec = selectedSpec and specs[selectedSpec]; if ( spec and spec.hasGlyphs and PanelTemplates_GetSelectedTab(PlayerTalentFrame) == GLYPH_TALENT_TAB ) then -- if the glyph tab is selected then toggle the frame off HideUIPanel(PlayerTalentFrame); hidden = true; else hidden = false; end end if ( not hidden ) then -- open the spec with the requested talent group (or the current talent group if the selected -- spec has one) if ( selectedSpec ) then local spec = specs[selectedSpec]; if ( spec.hasGlyphs ) then suggestedTalentGroup = spec.talentGroup; end end for _, index in ipairs(TALENT_SORT_ORDER) do local spec = specs[index]; if ( spec.hasGlyphs and spec.talentGroup == suggestedTalentGroup ) then PlayerSpecTab_OnClick(specTabs[index]); PlayerTalentTab_OnClick(_G["PlayerTalentFrameTab"..GLYPH_TALENT_TAB]); break; end end end endendfunction PlayerTalentFrame_OpenGlyphFrame(talentGroup) GlyphFrame_LoadUI(); if ( GlyphFrame ) then ShowUIPanel(PlayerTalentFrame); -- open the spec with the requested talent group for index, spec in next, specs do if ( spec.hasGlyphs and spec.talentGroup == talentGroup ) then PlayerSpecTab_OnClick(specTabs[index]); PlayerTalentTab_OnClick(_G["PlayerTalentFrameTab"..GLYPH_TALENT_TAB]); break; end end endendfunction PlayerTalentFrame_ShowGlyphFrame() GlyphFrame_LoadUI(); if ( GlyphFrame ) then -- set the title text of the GlyphFrame if ( selectedSpec and specs[selectedSpec].glyphName and GetNumTalentGroups() > 1 ) then GlyphFrameTitleText:SetText(specs[selectedSpec].glyphName); else GlyphFrameTitleText:SetText(GLYPHS); end -- show/update the glyph frame if ( GlyphFrame:IsShown() ) then GlyphFrame_Update(); else GlyphFrame:Show(); end -- don't forget to hide the scroll button overlay or it may show up on top of the GlyphFrame! UIFrameFlashStop(PlayerTalentFrameScrollButtonOverlay); endendfunction PlayerTalentFrame_HideGlyphFrame() if ( not GlyphFrame or not GlyphFrame:IsShown() ) then return; end GlyphFrame_LoadUI(); if ( GlyphFrame ) then GlyphFrame:Hide(); endendfunction PlayerTalentFrame_OnLoad(self) self:RegisterEvent("ADDON_LOADED"); self:RegisterEvent("PREVIEW_TALENT_POINTS_CHANGED"); self:RegisterEvent("PREVIEW_PET_TALENT_POINTS_CHANGED"); self:RegisterEvent("UNIT_PORTRAIT_UPDATE"); self:RegisterEvent("UNIT_PET"); self:RegisterEvent("PLAYER_LEVEL_UP"); self:RegisterEvent("PLAYER_TALENT_UPDATE"); self:RegisterEvent("PET_TALENT_UPDATE"); self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); self.unit = "player"; self.inspect = false; self.pet = false; self.talentGroup = 1; self.updateFunction = PlayerTalentFrame_Update; TalentFrame_Load(self); -- setup talent buttons local button; for i = 1, MAX_NUM_TALENTS do button = _G["PlayerTalentFrameTalent"..i]; if ( button ) then button:SetScript("OnClick", PlayerTalentFrameTalent_OnClick); button:SetScript("OnEvent", PlayerTalentFrameTalent_OnEvent); button:SetScript("OnEnter", PlayerTalentFrameTalent_OnEnter); end end -- setup tabs PanelTemplates_SetNumTabs(self, MAX_TALENT_TABS + 1); -- add one for the GLYPH_TALENT_TAB -- initialize active spec as a fail safe local activeTalentGroup = GetActiveTalentGroup(); local numTalentGroups = GetNumTalentGroups(); PlayerTalentFrame_UpdateActiveSpec(activeTalentGroup, numTalentGroups); -- setup active spec highlight if ( ACTIVESPEC_DISPLAYTYPE == "BLUE" ) then PlayerTalentFrameActiveSpecTabHighlight:SetDrawLayer("OVERLAY"); PlayerTalentFrameActiveSpecTabHighlight:SetBlendMode("ADD"); PlayerTalentFrameActiveSpecTabHighlight:SetTexture("Interface\Buttons\UI-Button-Outline"); elseif ( ACTIVESPEC_DISPLAYTYPE == "GOLD_INSIDE" ) then PlayerTalentFrameActiveSpecTabHighlight:SetDrawLayer("OVERLAY"tR·‡êv ctiveSpecTabHighlight:SetBlendMode("ADD"); PlayerTalentFrameActiveSpecTabHighlight:SetTexture("Interface\Buttons\CheckButtonHilight"); elseif ( ACTIVESPEC_DISPLAYTYPE == "GOLD_BACKGROUND" ) then PlayerTalentFrameActiveSpecTabHighlight:SetDrawLayer("BACKGROUND"); PlayerTalentFrameActiveSpecTabHighlight:SetWidth(74); PlayerTalentFrameActiveSpecTabHighlight:SetHeight(86); PlayerTalentFrameActiveSpecTabHighlight:SetTexture("Interface\SpellBook\SpellBook-SkillLineTab-Glow"); endendfunction PlayerTalentFrame_OnShow(self) -- Stop buttons from flashing after skill up SetButtonPulse(TalentMicroButton, 0, 1); PlaySound("TalentScreenOpen"); UpdateMicroButtons(); if ( not selectedSpec ) then -- if no spec was selected, try to select the active one PlayerSpecTab_OnClick(activeSpec and specTabs[activeSpec] or specTabs[DEFAULT_TALENT_SPEC]); else PlayerTalentFrame_Refresh(); end -- Set flag if ( not GetCVarBool("talentFrameShown") ) then SetCVar("talentFrameShown", 1); UIFrameFlash(PlayerTalentFrameScrollButtonOverlay, 0.5, 0.5, 60); endendfunction PlayerTalentFrame_OnHide() UpdateMicroButtons(); PlaySound("TalentScreenClose"); UIFrameFlashStop(PlayerTalentFrameScrollButtonOverlay); -- clear caches for _, info in next, talentSpecInfoCache do wipe(info); end wipe(talentTabWidthCache);endfunction PlayerTalentFrame_OnEvent(self, event, ...) if ( event == "PLAYER_TALENT_UPDATE" or event == "PET_TALENT_UPDATE" ) then PlayerTalentFrame_Refresh(); elseif ( event == "PREVIEW_TALENT_POINTS_CHANGED" ) then --local talentIndex, tabIndex, groupIndex, points = ...; if ( selectedSpec and not specs[selectedSpec].pet ) then PlayerTalentFrame_Refresh(); end elseif ( event == "PREVIEW_PET_TALENT_POINTS_CHANGED" ) then --local talentIndex, tabIndex, groupIndex, points = ...; if ( selectedSpec and specs[selectedSpec].pet ) then PlayerTalentFrame_Refresh(); end elseif ( event == "UNIT_PORTRAIT_UPDATE" ) then local unit = ...; -- update the talent frame's portrait if ( unit == PlayerTalentFramePortrait.unit ) then SetPortraitTexture(PlayerTalentFramePortrait, unit); end -- update spec tabs' portraits for _, frame in next, specTabs do if ( frame.usingPortraitTexture ) then local spec = specs[frame.specIndex]; if ( unit == spec.unit and spec.portraitUnit ) then SetPortraitTexture(frame:GetNormalTexture(), unit); end end end elseif ( event == "UNIT_PET" ) then local summoner = ...; if ( summoner == "player" ) then if ( selectedSpec and specs[selectedSpec].pet ) then -- if the selected spec is a pet spec... local numTalentGroups = GetNumTalentGroups(false, true); if ( numTalentGroups == 0 ) then --...and a pet spec is not available, select the default spec PlayerSpecTab_OnClick(activeSpec and specTabs[activeSpec] or specTabs[DEFAULT_TALENT_SPEC]); return; end end PlayerTalentFrame_Refresh(); end elseif ( event == "PLAYER_LEVEL_UP" ) then if ( selectedSpec and not specs[selectedSpec].pet ) then local level = ...; PlayerTalentFrame_Update(level); end elseif ( event == "ACTIVE_TALENT_GROUP_CHANGED" ) then MainMenuBar_ToPlayerArt(MainMenuBarArtFrame); endendfunction PlayerTalentFrame_Refresh() local selectedTab = PanelTemplates_GetSelectedTab(PlayerTalentFrame); if ( selectedTab == GLYPH_TALENT_TAB ) then PlayerTalentFrame_ShowGlyphFrame(); else PlayerTalentFrame_HideGlyphFrame(); end TalentFrame_Update(PlayerTalentFrame);endfunction PlayerTalentFrame_Update(playerLevel) local activeTalentGroup, numTalentGroups = GetActiveTalentGroup(false, false), GetNumTalentGroups(false, false); local activePetTalentGroup, numPetTalentGroups = GetActiveTalentGroup(false, true), GetNumTalentGroups(false, true); -- update specs if ( not PlayerTalentFrame_UpdateSpecs(activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups) ) thentR·‡êv s not selectable any more, discontinue updates return; end -- update tabs if ( not PlayerTalentFrame_UpdateTabs(playerLevel) ) then -- the current spec is not selectable any more, discontinue updates return; end -- set the frame portrait SetPortraitTexture(PlayerTalentFramePortrait, PlayerTalentFrame.unit); -- update active talent group stuff PlayerTalentFrame_UpdateActiveSpec(activeTalentGroup, numTalentGroups); -- update talent controls PlayerTalentFrame_UpdateControls(activeTalentGroup, numTalentGroups);endfunction PlayerTalentFrame_UpdateActiveSpec(activeTalentGroup, numTalentGroups) -- set the active spec activeSpec = DEFAULT_TALENT_SPEC; for index, spec in next, specs do if ( not spec.pet and spec.talentGroup == activeTalentGroup ) then activeSpec = index; break; end end -- make UI adjustments local spec = selectedSpec and specs[selectedSpec]; local hasMultipleTalentGroups = numTalentGroups > 1; if ( spec and hasMultipleTalentGroups ) then PlayerTalentFrameTitleText:SetText(spec.name); else PlayerTalentFrameTitleText:SetText(TALENTS); end if ( selectedSpec == activeSpec and hasMultipleTalentGroups ) then --PlayerTalentFrameActiveTalentGroupFrame:Show(); else PlayerTalentFrameActiveTalentGroupFrame:Hide(); endend-- PlayerTalentFrameTalentsfunction PlayerTalentFrameTalent_OnClick(self, button) if ( IsModifiedClick("CHATLINK") ) then local link = GetTalentLink(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), PlayerTalentFrame.inspect, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup, GetCVarBool("previewTalents")); if ( link ) then ChatEdit_InsertLink(link); end elseif ( selectedSpec and (activeSpec == selectedSpec or specs[selectedSpec].pet) ) then -- only allow functionality if an active spec is selected if ( button == "LeftButton" ) then if ( GetCVarBool("previewTalents") ) then AddPreviewTalentPoints(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), 1, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup); else LearnTalent(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup); end elseif ( button == "RightButton" ) then if ( GetCVarBool("previewTalents") ) then AddPreviewTalentPoints(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), -1, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup); end end endendfunction PlayerTalentFrameTalent_OnEvent(self, event, ...) if ( GameTooltip:IsOwned(self) ) then GameTooltip:SetTalent(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), PlayerTalentFrame.inspect, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup, GetCVarBool("previewTalents")); endendfunction PlayerTalentFrameTalent_OnEnter(self) GameTooltip:SetOwner(self, "ANCHOR_RIGHT"); GameTooltip:SetTalent(PanelTemplates_GetSelectedTab(PlayerTalentFrame), self:GetID(), PlayerTalentFrame.inspect, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup, GetCVarBool("previewTalents")); local canLearn = nil; local wrapRest = false; local l = GameTooltip:NumLines(); if (_G["GameTooltipTextLeft"..l]:GetText() == "Click to learn") then canLearn = true; wrapRest = true; l = l - 1; end local tmp = {}; local r = true; local i = 1; for c=1, l do r = true; local n = {}; local left = _G["GameTooltipTextLeft"..c]; local right = _G["GameTooltipTextRight"..c]; if ( left ) then n.w = true; n.r1, n.g1, n.b1 = left:GetTextColor(); local t = left:GetText(); if ( strsub(t, 1, 8) == "Requires" ) then n.w = wrapRest; if ( strsub(t, -7) == "Talents" ) then local d = tonumber(strmatch(t, "%d+")) / 5; t = gsub(t, "%d+", d); wrapRest = true; if ( d <= PlayerTalentFrame.pointsSpent + PlayerTalentFrame.previewPointsSpent ) then n.r1 = 1.0; n.g1 = 1.0; n.b1 = 1.0; r = false; if ( canLeartR·‡êv canLearn = true; end end elseif ( not wrapRest ) then canLearn = false; end end n.t1 = t; end if ( right ) then n.r2, n.g2, n.b2 = right:GetTextColor(); n.t2 = right:GetText(); end if ( r ) then tmp[i] = n; i = i + 1; end end i = nil; GameTooltip:ClearLines(); for i=1, #tmp do if ( tmp[i].t1 and tmp[i].t2 ) then GameTooltip:AddDoubleLine(tmp[i].t1, tmp[i].t2, tmp[i].r1, tmp[i].g1, tmp[i].b1, tmp[i].r2, tmp[i].g2, tmp[i].b2); elseif ( tmp[i].t1 ) then GameTooltip:AddLine(tmp[i].t1, tmp[i].r1, tmp[i].g1, tmp[i].b1, tmp[i].w); elseif ( tmp[i].t2 ) then GameTooltip:AddDoubleLine("", tmp[i].t2, 0, 0, 0, tmp[i].r2, tmp[i].g2, tmp[i].b2); end end if ( canLearn ) then GameTooltip:AddLine("Click to learn", 0, 1, 0, true); end GameTooltip:Show();end-- Controlsfunction PlayerTalentFrame_UpdateControls(activeTalentGroup, numTalentGroups) local spec = selectedSpec and specs[selectedSpec]; local isActiveSpec = selectedSpec == activeSpec; -- show the multi-spec status frame if this is not a pet spec or we have more than one talent group local showStatusFrame = not spec.pet and numTalentGroups > 1; -- show the activate button if we were going to show the status frame but this is not the active spec local showActivateButton = showStatusFrame and not isActiveSpec; if ( showActivateButton ) then PlayerTalentFrameActivateButton:Show(); PlayerTalentFrameStatusFrame:Hide(); else PlayerTalentFrameActivateButton:Hide(); if ( showStatusFrame ) then PlayerTalentFrameStatusFrame:Show(); else PlayerTalentFrameStatusFrame:Hide(); end end local preview = GetCVarBool("previewTalents"); -- enable the control bar if this is the active spec, preview is enabled, and preview points were spent local talentPoints = GetUnspentTalentPoints(false, spec.pet, spec.talentGroup); if ( (spec.pet or isActiveSpec) and talentPoints > 0 and preview ) then PlayerTalentFramePreviewBar:Show(); -- enable accept/cancel buttons if preview talent points were spent if ( GetGroupPreviewTalentPointsSpent(spec.pet, spec.talentGroup) > 0 ) then PlayerTalentFrameLearnButton:Enable(); PlayerTalentFrameResetButton:Enable(); else PlayerTalentFrameLearnButton:Disable(); PlayerTalentFrameResetButton:Disable(); end -- squish all frames to make room for this bar PlayerTalentFramePointsBar:SetPoint("BOTTOM", PlayerTalentFramePreviewBar, "TOP", 0, -4); else PlayerTalentFramePreviewBar:Hide(); -- unsquish frames since the bar is now hidden PlayerTalentFramePointsBar:SetPoint("BOTTOM", PlayerTalentFrame, "BOTTOM", 0, 81); endendfunction PlayerTalentFrameActivateButton_OnLoad(self) self:SetWidth(self:GetTextWidth() + 40);endfunction PlayerTalentFrameActivateButton_OnClick(self) if ( selectedSpec ) then local talentGroup = specs[selectedSpec].talentGroup; if ( talentGroup ) then SetActiveTalentGroup(talentGroup); end endendfunction PlayerTalentFrameActivateButton_OnShow(self) self:RegisterEvent("CURRENT_SPELL_CAST_CHANGED"); PlayerTalentFrameActivateButton_Update();endfunction PlayerTalentFrameActivateButton_OnHide(self) self:UnregisterEvent("CURRENT_SPELL_CAST_CHANGED");endfunction PlayerTalentFrameActivateButton_OnEvent(self, event, ...) PlayerTalentFrameActivateButton_Update();endfunction PlayerTalentFrameActivateButton_Update() local spec = selectedSpec and specs[selectedSpec]; if ( spec and PlayerTalentFrameActivateButton:IsShown() ) then -- if the activation spell is being cast currently, disable the activate button if ( IsCurrentSpell(TALENT_ACTIVATION_SPELLS[spec.talentGroup]) ) then PlayerTalentFrameActivateButton:Disable(); else PlayerTalentFrameActivateButton:Enable(); end endendfunction PlayerTalentFrameResetButton_OnEnter(self) GameTooltip:SetOwner(self, "ANCHOR_RIGHT"); GameTooltip:SetText(TALENT_TOOLTIP_RESETTALENTGROUP);endftR·‡êv eResetButton_OnClick(self) ResetGroupPreviewTalentPoints(PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup);endfunction PlayerTalentFrameLearnButton_OnEnter(self) GameTooltip:SetOwner(self, "ANCHOR_RIGHT"); GameTooltip:SetText(TALENT_TOOLTIP_LEARNTALENTGROUP);endfunction PlayerTalentFrameLearnButton_OnClick(self) StaticPopup_Show("CONFIRM_LEARN_PREVIEW_TALENTS");end-- PlayerTalentFrameDownArrowfunction PlayerTalentFrameDownArrow_OnClick(self, button) local parent = self:GetParent(); parent:SetValue(parent:GetValue() + (parent:GetHeight() / 2)); PlaySound("UChatScrollButton"); UIFrameFlashStop(PlayerTalentFrameScrollButtonOverlay);end-- PlayerTalentFrameTabfunction PlayerTalentFrame_UpdateTabs(playerLevel) local totalTabWidth = 0; local firstShownTab; -- setup talent tabs local maxPointsSpent = 0; local selectedTab = PanelTemplates_GetSelectedTab(PlayerTalentFrame); local numTabs = GetNumTalentTabs(PlayerTalentFrame.inspect, PlayerTalentFrame.pet); local tab; for i = 1, MAX_TALENT_TABS do -- clear cached widths talentTabWidthCache[i] = 0; tab = _G["PlayerTalentFrameTab"..i]; if ( tab ) then if ( i <= numTabs ) then local name, icon, pointsSpent, background, previewPointsSpent = GetTalentTabInfo(i, PlayerTalentFrame.inspect, PlayerTalentFrame.pet, PlayerTalentFrame.talentGroup); if ( i == selectedTab ) then -- If tab is the selected tab set the points spent info local displayPointsSpent = pointsSpent + previewPointsSpent; PlayerTalentFrameSpentPointsText:SetFormattedText(MASTERY_POINTS_SPENT, name, HIGHLIGHT_FONT_COLOR_CODE..displayPointsSpent..FONT_COLOR_CODE_CLOSE); PlayerTalentFrame.pointsSpent = pointsSpent; PlayerTalentFrame.previewPointsSpent = previewPointsSpent; end tab:SetText(name); PanelTemplates_TabResize(tab, 0); -- record the text width to see if we need to display a tooltip tab.textWidth = tab:GetTextWidth(); -- record the tab widths for resizing later talentTabWidthCache[i] = PanelTemplates_GetTabWidth(tab); totalTabWidth = totalTabWidth + talentTabWidthCache[i]; tab:Show(); firstShownTab = firstShownTab or tab; else tab:Hide(); tab.textWidth = 0; end end end local spec = specs[selectedSpec]; -- setup glyph tabs, right now there is only one playerLevel = playerLevel or UnitLevel("player"); local meetsGlyphLevel = playerLevel >= SHOW_INSCRIPTION_LEVEL; tab = _G["PlayerTalentFrameTab"..GLYPH_TALENT_TAB]; if ( meetsGlyphLevel and spec.hasGlyphs ) then tab:Show(); firstShownTab = firstShownTab or tab; PanelTemplates_TabResize(tab, 0); talentTabWidthCache[GLYPH_TALENT_TAB] = PanelTemplates_GetTabWidth(tab); totalTabWidth = totalTabWidth + talentTabWidthCache[GLYPH_TALENT_TAB]; else tab:Hide(); talentTabWidthCache[GLYPH_TALENT_TAB] = 0; end local numGlyphTabs = 1; -- select the first shown tab if the selected tab does not exist for the selected spec tab = _G["PlayerTalentFrameTab"..selectedTab]; if ( tab and not tab:IsShown() ) then if ( firstShownTab ) then PlayerTalentFrameTab_OnClick(firstShownTab); end return false; end -- readjust tab sizes to fit local maxTotalTabWidth = PlayerTalentFrame:GetWidth(); while ( totalTabWidth >= maxTotalTabWidth ) do -- progressively shave 10 pixels off of the largest tab until they all fit within the max width local largestTab = 1; for i = 2, #talentTabWidthCache do if ( talentTabWidthCache[largestTab] < talentTabWidthCache[i] ) then largestTab = i; end end -- shave the width talentTabWidthCache[largestTab] = talentTabWidthCache[largestTab] - 10; -- apply the shaved width tab = _G["PlayerTalentFrameTab"..largestTab]; PanelTemplates_TabResize(tab, 0, talentTabWidthCache[largestTab]); -- now update the total width totalTabWidth = totalTabWidth - 10; end -- update the tabs PanelTemplates_SetNumTabs(PlayerTalentFrame, numTabs + numtR·‡êv ates_UpdateTabs(PlayerTalentFrame); return true;endfunction PlayerTalentFrameTab_OnLoad(self) self:SetFrameLevel(self:GetFrameLevel() + 2);endfunction PlayerTalentFrameTab_OnClick(self) local id = self:GetID(); PanelTemplates_SetTab(PlayerTalentFrame, id); PlayerTalentFrame_Refresh(); PlaySound("igCharacterInfoTab");endfunction PlayerTalentFrameTab_OnEnter(self) if ( self.textWidth and self.textWidth > self:GetFontString():GetWidth() ) then --We're ellipsizing. GameTooltip:SetOwner(self, "ANCHOR_BOTTOM"); GameTooltip:SetText(self:GetText()); endend-- PlayerTalentTabfunction PlayerTalentTab_OnLoad(self) PlayerTalentFrameTab_OnLoad(self); self:RegisterEvent("PLAYER_LEVEL_UP");endfunction PlayerTalentTab_OnClick(self) PlayerTalentFrameTab_OnClick(self); for i=1, MAX_TALENT_TABS do SetButtonPulse(_G["PlayerTalentFrameTab"..i], 0, 0); endendfunction PlayerTalentTab_OnEvent(self, event, ...) if ( UnitLevel("player") == (SHOW_TALENT_LEVEL - 1) and PanelTemplates_GetSelectedTab(PlayerTalentFrame) ~= self:GetID() ) then SetButtonPulse(self, 60, 0.75); endendfunction PlayerTalentTab_GetBestDefaultTab(specIndex) if ( not specIndex ) then return DEFAULT_TALENT_TAB; end local spec = specs[specIndex]; if ( not spec ) then return DEFAULT_TALENT_TAB; end local specInfoCache = talentSpecInfoCache[specIndex]; TalentFrame_UpdateSpecInfoCache(specInfoCache, false, spec.pet, spec.talentGroup); if ( specInfoCache.primaryTabIndex > 0 ) then return talentSpecInfoCache[specIndex].primaryTabIndex; else return DEFAULT_TALENT_TAB; endend-- PlayerGlyphTabfunction PlayerGlyphTab_OnLoad(self) PlayerTalentFrameTab_OnLoad(self); self:RegisterEvent("PLAYER_LEVEL_UP"); GLYPH_TALENT_TAB = self:GetID(); -- we can record the text width for the glyph tab now since it never changes self.textWidth = self:GetTextWidth();endfunction PlayerGlyphTab_OnClick(self) PlayerTalentFrameTab_OnClick(self); SetButtonPulse(_G["PlayerTalentFrameTab"..GLYPH_TALENT_TAB], 0, 0);endfunction PlayerGlyphTab_OnEvent(self, event, ...) if ( UnitLevel("player") == (SHOW_INSCRIPTION_LEVEL - 1) and PanelTemplates_GetSelectedTab(PlayerTalentFrame) ~= self:GetID() ) then SetButtonPulse(self, 60, 0.75); endend-- Specs-- PlayerTalentFrame_UpdateSpecs is a helper function for PlayerTalentFrame_Update.-- Returns true on a successful update, false otherwise. An update may fail if the currently-- selected tab is no longer selectable. In this case, the first selectable tab will be selected.function PlayerTalentFrame_UpdateSpecs(activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups) -- set the active spec highlight to be hidden initially, if a spec is the active one then it will -- be shown in PlayerSpecTab_Update PlayerTalentFrameActiveSpecTabHighlight:Hide(); -- update each of the spec tabs local firstShownTab, lastShownTab; local numShown = 0; local offsetX = 0; for i = 1, numSpecTabs do local frame = _G["PlayerSpecTab"..i]; local specIndex = frame.specIndex; local spec = specs[specIndex]; if ( PlayerSpecTab_Update(frame, activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups) ) then firstShownTab = firstShownTab or frame; numShown = numShown + 1; frame:ClearAllPoints(); -- set an offsetX fudge if we're the selected tab, otherwise use the previous offsetX offsetX = specIndex == selectedSpec and SELECTEDSPEC_OFFSETX or offsetX; if ( numShown == 1 ) then --...start the first tab off at a base location frame:SetPoint("TOPLEFT", frame:GetParent(), "TOPRIGHT", -32 + offsetX, -65); -- we'll need to negate the offsetX after the first tab so all subsequent tabs offset -- to their default positions offsetX = -offsetX; else --...offset subsequent tabs from the previous one if ( spec.pet ~= specs[lastShownTab.specIndex].pet ) then frame:SetPoint("TOtR·‡êv OTTOMLEFT", 0 + offsetX, -39); else frame:SetPoint("TOPLEFT", lastShownTab, "BOTTOMLEFT", 0 + offsetX, -22); end end lastShownTab = frame; else -- if the selected tab is not shown then clear out the selected spec if ( specIndex == selectedSpec ) then selectedSpec = nil; end end end if ( not selectedSpec ) then if ( firstShownTab ) then PlayerSpecTab_OnClick(firstShownTab); end return false; end if ( numShown == 1 and lastShownTab ) then -- if we're only showing one tab, we might as well hide it since it doesn't need to be there lastShownTab:Hide(); end return true;endfunction PlayerSpecTab_Update(self, ...) local activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups = ...; local specIndex = self.specIndex; local spec = specs[specIndex]; -- determine whether or not we need to hide the tab local canShow; if ( spec.pet ) then canShow = spec.talentGroup <= numPetTalentGroups; else canShow = spec.talentGroup <= numTalentGroups; end if ( not canShow ) then self:Hide(); return false; end local isSelectedSpec = specIndex == selectedSpec; local isActiveSpec = not spec.pet and spec.talentGroup == activeTalentGroup; local normalTexture = self:GetNormalTexture(); -- set the background based on whether or not we're selected if ( isSelectedSpec and (SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT" or SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT_CHECKED") ) then local name = self:GetName(); local backgroundTexture = _G[name.."Background"]; backgroundTexture:SetTexture("Interface\TalentFrame\UI-TalentFrame-SpecTab"); backgroundTexture:SetPoint("TOPLEFT", self, "TOPLEFT", -13, 11); if ( SELECTEDSPEC_DISPLAYTYPE == "PUSHED_OUT_CHECKED" ) then self:GetCheckedTexture():Show(); else self:GetCheckedTexture():Hide(); end else local name = self:GetName(); local backgroundTexture = _G[name.."Background"]; backgroundTexture:SetTexture("Interface\SpellBook\SpellBook-SkillLineTab"); backgroundTexture:SetPoint("TOPLEFT", self, "TOPLEFT", -3, 11); end -- update the active spec info local hasMultipleTalentGroups = numTalentGroups > 1; if ( isActiveSpec and hasMultipleTalentGroups ) then PlayerTalentFrameActiveSpecTabHighlight:ClearAllPoints(); if ( ACTIVESPEC_DISPLAYTYPE == "BLUE" ) then PlayerTalentFrameActiveSpecTabHighlight:SetParent(self); PlayerTalentFrameActiveSpecTabHighlight:SetPoint("TOPLEFT", self, "TOPLEFT", -13, 14); PlayerTalentFrameActiveSpecTabHighlight:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 15, -14); PlayerTalentFrameActiveSpecTabHighlight:Show(); elseif ( ACTIVESPEC_DISPLAYTYPE == "GOLD_INSIDE" ) then PlayerTalentFrameActiveSpecTabHighlight:SetParent(self); PlayerTalentFrameActiveSpecTabHighlight:SetAllPoints(self); PlayerTalentFrameActiveSpecTabHighlight:Show(); elseif ( ACTIVESPEC_DISPLAYTYPE == "GOLD_BACKGROUND" ) then PlayerTalentFrameActiveSpecTabHighlight:SetParent(self); PlayerTalentFrameActiveSpecTabHighlight:SetPoint("TOPLEFT", self, "TOPLEFT", -3, 20); PlayerTalentFrameActiveSpecTabHighlight:Show(); else PlayerTalentFrameActiveSpecTabHighlight:Hide(); end end--[[ if ( not spec.pet ) then SetDesaturation(normalTexture, not isActiveSpec); end--]] -- update the spec info cache TalentFrame_UpdateSpecInfoCache(talentSpecInfoCache[specIndex], false, spec.pet, spec.talentGroup); -- update spec tab icon self.usingPortraitTexture = false; if ( hasMultipleTalentGroups ) then local specInfoCache = talentSpecInfoCache[specIndex]; local primaryTabIndex = specInfoCache.primaryTabIndex; if ( primaryTabIndex > 0 ) then -- the spec had a primary tab, set the icon to that tab's icon normalTexture:SetTexture(specInfoCache[primaryTabIndex].icon); else if ( specInfoCache.numTabs > 1 and specInfoCache.totalPointsSpent > 0 ) then -- the spec is only considered a hybrid if the spec had more than ontR·‡êv -- one point was spent in one of the tabs normalTexture:SetTexture(TALENT_HYBRID_ICON); else if ( spec.defaultSpecTexture ) then -- the spec is probably untalented...set to the default spec texture if we have one normalTexture:SetTexture(spec.defaultSpecTexture); elseif ( spec.portraitUnit ) then -- last check...if there is no default spec texture, try the portrait unit SetPortraitTexture(normalTexture, spec.portraitUnit); self.usingPortraitTexture = true; end end end else if ( spec.portraitUnit ) then -- set to the portrait texture if we only have one talent group SetPortraitTexture(normalTexture, spec.portraitUnit); self.usingPortraitTexture = true; end end--[[ -- update overlay icon local name = self:GetName(); local overlayIcon = _G[name.."OverlayIcon"]; if ( overlayIcon ) then if ( hasMultipleTalentGroups ) then overlayIcon:Show(); else overlayIcon:Hide(); end end--]] self:Show(); return true;endfunction PlayerSpecTab_Load(self, specIndex) self.specIndex = specIndex; specTabs[specIndex] = self; numSpecTabs = numSpecTabs + 1; -- set the spec's portrait local spec = specs[self.specIndex]; if ( spec.portraitUnit ) then SetPortraitTexture(self:GetNormalTexture(), spec.portraitUnit); self.usingPortraitTexture = true; else self.usingPortraitTexture = false; end -- set the checked texture if ( SELECTEDSPEC_DISPLAYTYPE == "BLUE" ) then local checkedTexture = self:GetCheckedTexture(); checkedTexture:SetTexture("Interface\Buttons\UI-Button-Outline"); checkedTexture:SetWidth(64); checkedTexture:SetHeight(64); checkedTexture:ClearAllPoints(); checkedTexture:SetPoint("CENTER", self, "CENTER", 0, 0); elseif ( SELECTEDSPEC_DISPLAYTYPE == "GOLD_INSIDE" ) then local checkedTexture = self:GetCheckedTexture(); checkedTexture:SetTexture("Interface\Buttons\CheckButtonHilight"); end local activeTalentGroup, numTalentGroups = GetActiveTalentGroup(false, false), GetNumTalentGroups(false, false); local activePetTalentGroup, numPetTalentGroups = GetActiveTalentGroup(false, true), GetNumTalentGroups(false, true); PlayerSpecTab_Update(self, activeTalentGroup, numTalentGroups, activePetTalentGroup, numPetTalentGroups);endfunction PlayerSpecTab_OnClick(self) -- set all specs as unchecked initially for _, frame in next, specTabs do frame:SetChecked(nil); end -- check ourselves (before we wreck ourselves) self:SetChecked(1); -- update the selected to this spec local specIndex = self.specIndex; selectedSpec = specIndex; -- set data on the talent frame local spec = specs[specIndex]; PlayerTalentFrame.pet = spec.pet; PlayerTalentFrame.unit = spec.unit; PlayerTalentFrame.talentGroup = spec.talentGroup; -- select a tab if one is not already selected if ( not PanelTemplates_GetSelectedTab(PlayerTalentFrame) ) then PanelTemplates_SetTab(PlayerTalentFrame, PlayerTalentTab_GetBestDefaultTab(specIndex)); end -- update the talent frame PlayerTalentFrame_Refresh();endfunction PlayerSpecTab_OnEnter(self) local specIndex = self.specIndex; local spec = specs[specIndex]; if ( spec.tooltip ) then GameTooltip:SetOwner(self, "ANCHOR_RIGHT"); -- name if ( GetNumTalentGroups(false, true) <= 1 and GetNumTalentGroups(false, false) <= 1 ) then -- set the tooltip to be the unit's name GameTooltip:AddLine(UnitName(spec.unit), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); else -- set the tooltip to be the spec name GameTooltip:AddLine(spec.tooltip); if ( self.specIndex == activeSpec ) then -- add text to indicate that this spec is active GameTooltip:AddLine(TALENT_ACTIVE_SPEC_STATUS, GREEN_FONT_COLOR.r, GREEN_FONT_COLOR.g, GREEN_FONT_COLOR.b); end end -- points spent local pointsColor; for index, info in ipairs(talentSpecInfoCache[specIndex]) do if ( info.name ) then -- assign a special color to a tab thatR·‡êv ts spent threshold if ( talentSpecInfoCache[specIndex].primaryTabIndex == index ) then pointsColor = GREEN_FONT_COLOR; else pointsColor = HIGHLIGHT_FONT_COLOR; end GameTooltip:AddDoubleLine( info.name, info.pointsSpent, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b, pointsColor.r, pointsColor.g, pointsColor.b, 1 ); end end GameTooltip:Show(); endenditUnit); self.usin
Nope I was wrong. I know what it is. Its's the Preview Talent Changes feature. It still thinks you need 5 talent points. So lua edits have to be made to that too.
if ( ((tier - 1) * (TalentFrame.pet and PET_TALENTS_PER_TIER or PLAYER_TALENTS_PER_TIER) <= tabPointsSpent) ) then tierUnlocked = 1; else tierUnlocked = nil; end
--if ( ((tier - 1) * (TalentFrame.pet and PET_TALENTS_PER_TIER or PLAYER_TALENTS_PER_TIER) <= tabPointsSpent) ) then tierUnlocked = 1; --else --tierUnlocked = nil; --end
PLAYER_TALENTS_PER_TIER = 5;
PLAYER_TALENTS_PER_TIER = 0;
if ( ((tier - 1) * (TalentFrame.pet and PET_TALENTS_PER_TIER or PLAYER_TALENTS_PER_TIER) <= tabPointsSpent) ) then tierUnlocked = 1;else tierUnlocked = nil;end
-- if ( ((tier - 1) * (TalentFrame.pet and PET_TALENTS_PER_TIER or PLAYER_TALENTS_PER_TIER) <= tabPointsSpent) ) then tierUnlocked = 1;-- else-- tierUnlocked = nil;-- end
// not have required min points spent in talent tree if (spentPoints < (talentInfo->Row * MAX_TALENT_RANK)) return;
// not have required min points spent in talent tree // if (spentPoints < (talentInfo->Row * MAX_TALENT_RANK)) // return;