struct TalentEntry{ uint32 TalentID; // 0 uint32 TalentTab; // 1 index in TalentTab.dbc (TalentTabEntry) uint32 Row; // 2 uint32 Col; // 3 uint32 RankID[MAX_TALENT_RANK]; // 4-8 // 9-12 not used, always 0, maybe not used high ranks uint32 DependsOn; // 13 index in Talent.dbc (TalentEntry) // 14-15 not used uint32 DependsOnRank; // 16 // 17-18 not used //uint32 needAddInSpellBook; // 19 also need disable higest ranks on reset talent tree //uint32 unk2; // 20, all 0 //uint64 allowForPet; // 21 its a 64 bit mask for pet 1<<m_categoryEnumID in CreatureFamily.dbc};struct TalentTabEntry{ uint32 TalentTabID; // 0 //char* name[16]; // 1-16, unused //uint32 nameFlags; // 17, unused //unit32 spellicon; // 18 // 19 not used uint32 ClassMask; // 20 uint32 petTalentMask; // 21 uint32 tabpage; // 22 //char* internalname; // 23};
PLAYER_TALENTS_PER_TIER = NUMBER TO UNLOCK NEXT TIER;
PLAYER_TALENTS_PER_TIER = 2;
MAX_TALENT_GROUPS = 2;MAX_TALENT_TABS = 4;MAX_NUM_TALENT_TIERS = 15;NUM_TALENT_COLUMNS = 4;MAX_NUM_TALENTS = 40;PLAYER_TALENTS_PER_TIER = 2;PET_TALENTS_PER_TIER = 3;DEFAULT_TALENT_SPEC = "spec1";DEFAULT_TALENT_TAB = 1;TALENT_BUTTON_SIZE = 32;MAX_NUM_BRANCH_TEXTURES = 30;MAX_NUM_ARROW_TEXTURES = 30;INITIAL_TALENT_OFFSET_X = 35;INITIAL_TALENT_OFFSET_Y = 20;TALENT_HYBRID_ICON = "Interface\Icons\Ability_DualWieldSpecialization";TALENT_BRANCH_TEXTURECOORDS = { up = { [1] = {0.12890625, 0.25390625, 0 , 0.484375}, [-1] = {0.12890625, 0.25390625, 0.515625 , 1.0} }, down = { [1] = {0, 0.125, 0, 0.484375}, [-1] = {0, 0.125, 0.515625, 1.0} }, left = { [1] = {0.2578125, 0.3828125, 0, 0.5}, [-1] = {0.2578125, 0.3828125, 0.5, 1.0} }, right = { [1] = {0.2578125, 0.3828125, 0, 0.5}, [-1] = {0.2578125, 0.3828125, 0.5, 1.0} }, topright = { [1] = {0.515625, 0.640625, 0, 0.5}, [-1] = {0.515625, 0.640625, 0.5, 1.0} }, topleft = { [1] = {0.640625, 0.515625, 0, 0.5}, [-1] = {0.640625, 0.515625, 0.5, 1.0} }, bottomright = { [1] = {0.38671875, 0.51171875, 0, 0.5}, [-1] = {0.38671875, 0.51171875, 0.5, 1.0} }, bottomleft = { [1] = {0.51171875, 0.38671875, 0, 0.5}, [-1] = {0.51171875, 0.38671875, 0.5, 1.0} }, tdown = { [1] = {0.64453125, 0.76953125, 0, 0.5}, [-1] = {0.64453125, 0.76953125, 0.5, 1.0} }, tup = { [1] = {0.7734375, 0.8984375, 0, 0.5}, [-1] = {0.7734375, 0.8984375, 0.5, 1.0} },};TALENT_ARROW_TEXTURECOORDS = { top = { [1] = {0, 0.5, 0, 0.5}, [-1] = {0, 0.5, 0.5, 1.0} }, right = { [1] = {1.0, 0.5, 0, 0.5}, [-1] = {1.0, 0.5, 0.5, 1.0} }, left = { [1] = {0.5, 1.0, 0, 0.5}, [-1] = {0.5, 1.0, 0.5, 1.0} },};local min = min;local max = max;local huge = math.huge;local rshift = bit.rshift;function TalentFrame_Load(TalentFrame) TalentFrame.TALENT_BRANCH_ARRAY={}; for i=1, MAX_NUM_TALENT_TIERS do TalentFrame.TALENT_BRANCH_ARRAY[i] = {}; for j=1, NUM_TALENT_COLUMNS do TalentFrame.TALENT_BRANCH_ARRAY[i][j] = {id=nil, up=0, left=0, right=0, down=0, leftArrow=0, rightArrow=0, topArrow=0}; end endendfunction TalentFrame_Update(TalentFrame) if ( not TalentFrame ) then return; end if ( TalentFrame.updateFunction ) then TalentFrame.updateFunction(); end local talentFrameName = TalentFrame:GetName(); local selectedTab = PanelTemplates_GetSelectedTab(TalentFrame); local preview = GetCVarBool("previewTalents"); -- get active talent group local isActiveTalentGroup; if ( TalentFrame.inspect ) then -- even though we have inspection data for more than one talent group, we're only showing one for now isActiveTalentGroup = true; else isActiveTalentGroup = TalentFrame.talentGroup == GetActiveTalentGroup(TalentFrame.inspect, TalentFrame.pet); end -- Setup Frame local base; local name, icon, pointsSpent, background, previewPointsSpent = GetTalentTabInfo(selectedTab, TalentFrame.inspect, TalentFrame.pet, TalentFrame.talentGroup); if ( name ) then base = "Interface\TalentFrame\"..background.."-"; else -- temporary default for classes without talents poor guys base = "Interface\TalentFrame\MageFire-"; end -- desaturate the background if this isn't the active talent group local backgroundPiece = _G[talentFrameName.."BackgroundTopLeft"]; backgroundPiece:SetTexture(base.."TopLeft"); SetDesaturation(backgroundPiece, not isActiveTalentGroup); backgroundPiece = _G[talentFrameName.."BackgroundTopRight"]; backgroundPiece:SetTexture(base.."TopRight"); SetDesaturation(backgroundPiece, not isActiveTalentGroup); backgroundPiece = _G[talentFrameName.."BackgroundBottomLeft"]; backgroundPiece:SetTexture(base.."BottomLeft"); SetDesaturation(backgroundPiece, not isActiveTalentGroup); backgroundPiece = _G[talentFrameName.."BackgroundBottomRight"]; backgroundPiece:SetTexture(base.."BottomRight"); SetDesaturation(backgroundPiece, not isActiveTalentGroup); local numTalents = GetNumTalents(selectedTab, TalentFrame.inspect, TalentFrame.pet); -- Just a reminder error if there are more talents than available buttons if ( numTalents > MAX_NUM_TALENTS ) then message("Too many talents in talent frame!"); end -- get unspent talent points local unspentPoints = TalentFrame_UpdateTalentPoints(TalentFrame); -- compute tab points spent if any local tabPointsSpent; if ( TalentFrame.pointsSpent and TalentFrame.previewPointsSpent ) then tabPointsSpent = TalentFrame.pointsSpent + TalentFrame.previewPointsSpent; else tabPointsSpent = 0; end TalentFrame_ResetBranches(TalentFrame); local talentFrameTalentName = talentFrameName.."Talent"; local forceDesaturated, tierUnlocked; for i=1, MAX_NUM_TALENTS do local buttonName = talentFrameTalentName..i; local button = _G[buttonName]; if ( i <= numTalents ) then -- Set the button info local name, iconTexture, tier, column, rank, maxRank, isExceptional, meetsPrereq, previewRank, meetsPreviewPrereq = GetTalentInfo(selectedTab, i, TalentFrame.inspect, TalentFrame.pet, TalentFrame.talentGroup); if ( name ) then local displayRank; if ( preview ) then displayRank = previewRank; else displayRank = rank; end _G[buttonName.."Rank"]:SetText(displayRank); SetTalentButtonLocation(button, tier, column); TalentFrame.TALENT_BRANCH_ARRAY[tier][column].id = button:GetID(); -- If player has no talent points or this is the inactive talent group then show only talents with points in them if ( (unspentPoints <= 0 or not isActiveTalentGroup) and displayRank == 0 ) then forceDesaturated = 1; else forceDesaturated = nil; end -- is this talent's tier unlocked? if ( ((tier - 1) * (TalentFrame.pet and PET_TALENTS_PER_TIER or PLAYER_TALENTS_PER_TIER) <= tabPointsSpent) ) then tierUnlocked = 1; else tierUnlocked = nil; end SetItemButtonTexture(button, iconTexture); -- Talent must meet prereqs or the player must have no points to spend local prereqsSet = TalentFrame_SetPrereqs(TalentFrame, tier, column, forceDesaturated, tierUnlocked, preview, GetTalentPrereqs(selectedTab, i, TalentFrame.inspect, TalentFrame.pet, TalentFrame.talentGroup)); if ( prereqsSet and ((preview and meetsPreviewPrereq) or (not preview and meetsPrereq)) ) then SetItemButtonDesaturated(button, nil); if ( displayRank < maxRank ) then -- Rank is green if not maxed out _G[buttonName.."Slot"]:SetVertexColor(0.1, 1.0, 0.1); _G[buttonName.."Rank"]:SetTextColor(GREEN_FONT_COLOR.r, GREEN_FONT_COLOR.g, GREEN_FONT_COLOR.b); else _G[buttonName.."Slot"]:SetVertexColor(1.0, 0.82, 0); _G[buttonName.."Rank"]:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b); end _G[buttonName.."RankBorder"]:Show(); _G[buttonName.."Rank"]:Show(); else SetItemButtonDesaturated(button, 1, 0.65, 0.65, 0.65); _G[buttonName.."Slot"]:SetVertexColor(0.5, 0.5, 0.5); if ( rank == 0 ) then _G[buttonName.."RankBorder"]:Hide(); _G[buttonName.."Rank"]:Hide(); else _G[buttonName.."RankBorder"]:SetVertexColor(0.5, 0.5, 0.5); _G[buttonName.."Rank"]:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b); end end button:Show(); else button:Hide(); end else button:Hide(); end end -- Draw the prereq branches local node; local textureIndex = 1; local xOffset, yOffset; local texCoords; -- Variable that decides whether or not to ignore drawing pieces local ignoreUp; local tempNode; TalentFrame_ResetBranchTextureCount(TalentFrame); TalentFrame_ResetArrowTextureCount(TalentFrame); for i=1, MAX_NUM_TALENT_TIERS do for j=1, NUM_TALENT_COLUMNS do node = TalentFrame.TALENT_BRANCH_ARRAY[i][j]; -- Setup offsets xOffset = ((j - 1) * 63) + INITIAL_TALENT_OFFSET_X + 2; yOffset = -((i - 1) * 63) - INITIAL_TALENT_OFFSET_Y - 2; if ( node.id ) then -- Has talent if ( node.up ~= 0 ) then if ( not ignoreUp ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["up"][node.up], xOffset, yOffset + TALENT_BUTTON_SIZE, TalentFrame); else ignoreUp = nil; end end if ( node.down ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["down"][node.down], xOffset, yOffset - TALENT_BUTTON_SIZE + 1, TalentFrame); end if ( node.left ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["left"][node.left], xOffset - TALENT_BUTTON_SIZE, yOffset, TalentFrame); end if ( node.right ~= 0 ) then -- See if any connecting branches are gray and if so color them gray tempNode = TalentFrame.TALENT_BRANCH_ARRAY[i][j+1]; if ( tempNode.left ~= 0 and tempNode.down < 0 ) then TalentFrame_SetBranchTexture(i, j-1, TALENT_BRANCH_TEXTURECOORDS["right"][tempNode.down], xOffset + TALENT_BUTTON_SIZE, yOffset, TalentFrame); else TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["right"][node.right], xOffset + TALENT_BUTTON_SIZE + 1, yOffset, TalentFrame); end end -- Draw arrows if ( node.rightArrow ~= 0 ) then TalentFrame_SetArrowTexture(i, j, TALENT_ARROW_TEXTURECOORDS["right"][node.rightArrow], xOffset + TALENT_BUTTON_SIZE/2 + 5, yOffset, TalentFrame); end if ( node.leftArrow ~= 0 ) then TalentFrame_SetArrowTexture(i, j, TALENT_ARROW_TEXTURECOORDS["left"][node.leftArrow], xOffset - TALENT_BUTTON_SIZE/2 - 5, yOffset, TalentFrame); end if ( node.topArrow ~= 0 ) then TalentFrame_SetArrowTexture(i, j, TALENT_ARROW_TEXTURECOORDS["top"][node.topArrow], xOffset, yOffset + TALENT_BUTTON_SIZE/2 + 5, TalentFrame); end else -- Doesn't have a talent if ( node.up ~= 0 and node.left ~= 0 and node.right ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["tup"][node.up], xOffset , yOffset, TalentFrame); elseif ( node.down ~= 0 and node.left ~= 0 and node.right ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["tdown"][node.down], xOffset , yOffset, TalentFrame); elseif ( node.left ~= 0 and node.down ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["topright"][node.left], xOffset , yOffset, TalentFrame); TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["down"][node.down], xOffset , yOffset - 32, TalentFrame); elseif ( node.left ~= 0 and node.up ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["bottomright"][node.left], xOffset , yOffset, TalentFrame); elseif ( node.left ~= 0 and node.right ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["right"][node.right], xOffset + TALENT_BUTTON_SIZE, yOffset, TalentFrame); TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["left"][node.left], xOffset + 1, yOffset, TalentFrame); elseif ( node.right ~= 0 and node.down ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["topleft"][node.right], xOffset , yOffset, TalentFrame); TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["down"][node.down], xOffset , yOffset - 32, TalentFrame); elseif ( node.right ~= 0 and node.up ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["bottomleft"][node.right], xOffset , yOffset, TalentFrame); elseif ( node.up ~= 0 and node.down ~= 0 ) then TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["up"][node.up], xOffset , yOffset, TalentFrame); TalentFrame_SetBranchTexture(i, j, TALENT_BRANCH_TEXTURECOORDS["down"][node.down], xOffset , yOffset - 32, TalentFrame); ignoreUp = 1; end end end end -- Hide any unused branch textures for i=TalentFrame_GetBranchTextureCount(TalentFrame), MAX_NUM_BRANCH_TEXTURES do _G[talentFrameName.."Branch"..i]:Hide(); end -- Hide and unused arrowl textures for i=TalentFrame_GetArrowTextureCount(TalentFrame), MAX_NUM_ARROW_TEXTURES do _G[talentFrameName.."Arrow"..i]:Hide(); endendfunction TalentFrame_SetArrowTexture(tier, column, texCoords, xOffset, yOffset, TalentFrame) local talentFrameName = TalentFrame:GetName(); local arrowTexture = TalentFrame_GetArrowTexture(TalentFrame); arrowTexture:SetTexCoord(texCoords[1], texCoords[2], texCoords[3], texCoords[4]); arrowTexture:SetPoint("TOPLEFT", talentFrameName.."ArrowFrame", "TOPLEFT", xOffset, yOffset);endfunction TalentFrame_SetBranchTexture(tier, column, texCoords, xOffset, yOffset, TalentFrame) local talentFrameName = TalentFrame:GetName(); local branchTexture = TalentFrame_GetBranchTexture(TalentFrame); branchTexture:SetTexCoord(texCoords[1], texCoords[2], texCoords[3], texCoords[4]); branchTexture:SetPoint("TOPLEFT", talentFrameName.."ScrollChildFrame", "TOPLEFT", xOffset, yOffset);endfunction TalentFrame_GetArrowTexture(TalentFrame) local talentFrameName = TalentFrame:GetName(); local arrowTexture = _G[talentFrameName.."Arrow"..TalentFrame.arrowIndex]; TalentFrame.arrowIndex = TalentFrame.arrowIndex + 1; if ( not arrowTexture ) then message("Not enough arrow textures"); else arrowTexture:Show(); return arrowTexture; endendfunction TalentFrame_GetBranchTexture(TalentFrame) local talentFrameName = TalentFrame:GetName(); local branchTexture = _G[talentFrameName.."Branch"..TalentFrame.textureIndex]; TalentFrame.textureIndex = TalentFrame.textureIndex + 1; if ( not branchTexture ) then --branchTexture = CreateTexture("TalentFrameBranch"..TalentFrame.textureIndex); message("Not enough branch textures"); else branchTexture:Show(); return branchTexture; endendfunction TalentFrame_ResetArrowTextureCount(TalentFrame) TalentFrame.arrowIndex = 1;endfunction TalentFrame_ResetBranchTextureCount(TalentFrame) TalentFrame.textureIndex = 1;endfunction TalentFrame_GetArrowTextureCount(TalentFrame) return TalentFrame.arrowIndex;endfunction TalentFrame_GetBranchTextureCount(TalentFrame) return TalentFrame.textureIndex;endfunction TalentFrame_SetPrereqs(TalentFrame, buttonTier, buttonColumn, forceDesaturated, tierUnlocked, preview, ...) local requirementsMet = tierUnlocked and not forceDesaturated; for i=1, select("#", ...), 4 do local tier, column, isLearnable, isPreviewLearnable = select(i, ...); if ( forceDesaturated or (preview and not isPreviewLearnable) or (not preview and not isLearnable) ) then requirementsMet = nil; end TalentFrame_DrawLines(buttonTier, buttonColumn, tier, column, requirementsMet, TalentFrame); end return requirementsMet;endfunction TalentFrame_DrawLines(buttonTier, buttonColumn, tier, column, requirementsMet, TalentFrame) if ( requirementsMet ) then requirementsMet = 1; else requirementsMet = -1; end -- Check to see if are in the same column if ( buttonColumn == column ) then -- Check for blocking talents if ( (buttonTier - tier) > 1 ) then -- If more than one tier difference for i=tier + 1, buttonTier - 1 do if ( TalentFrame.TALENT_BRANCH_ARRAY[i][buttonColumn].id ) then -- If there's an id, there's a blocker message("Error this layout is blocked vertically "..TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][i].id); return; end end end -- Draw the lines for i=tier, buttonTier - 1 do TalentFrame.TALENT_BRANCH_ARRAY[i][buttonColumn].down = requirementsMet; if ( (i + 1) <= (buttonTier - 1) ) then TalentFrame.TALENT_BRANCH_ARRAY[i + 1][buttonColumn].up = requirementsMet; end end -- Set the arrow TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][buttonColumn].topArrow = requirementsMet; return; end -- Check to see if they're in the same tier if ( buttonTier == tier ) then local left = min(buttonColumn, column); local right = max(buttonColumn, column); -- See if the distance is greater than one space if ( (right - left) > 1 ) then -- Check for blocking talents for i=left + 1, right - 1 do if ( TalentFrame.TALENT_BRANCH_ARRAY[tier][i].id ) then -- If there's an id, there's a blocker message("there's a blocker "..tier.." "..i); return; end end end -- If we get here then we're in the clear for i=left, right - 1 do TalentFrame.TALENT_BRANCH_ARRAY[tier][i].right = requirementsMet; TalentFrame.TALENT_BRANCH_ARRAY[tier][i+1].left = requirementsMet; end -- Determine where the arrow goes if ( buttonColumn < column ) then TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][buttonColumn].rightArrow = requirementsMet; else TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][buttonColumn].leftArrow = requirementsMet; end return; end -- Now we know the prereq is diagonal from us local left = min(buttonColumn, column); local right = max(buttonColumn, column); -- Don't check the location of the current button if ( left == column ) then left = left + 1; else right = right - 1; end -- Check for blocking talents local blocked = nil; for i=left, right do if ( TalentFrame.TALENT_BRANCH_ARRAY[tier][i].id ) then -- If there's an id, there's a blocker blocked = 1; end end left = min(buttonColumn, column); right = max(buttonColumn, column); if ( not blocked ) then TalentFrame.TALENT_BRANCH_ARRAY[tier][buttonColumn].down = requirementsMet; TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][buttonColumn].up = requirementsMet; for i=tier, buttonTier - 1 do TalentFrame.TALENT_BRANCH_ARRAY[i][buttonColumn].down = requirementsMet; TalentFrame.TALENT_BRANCH_ARRAY[i + 1][buttonColumn].up = requirementsMet; end for i=left, right - 1 do TalentFrame.TALENT_BRANCH_ARRAY[tier][i].right = requirementsMet; TalentFrame.TALENT_BRANCH_ARRAY[tier][i+1].left = requirementsMet; end -- Place the arrow TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][buttonColumn].topArrow = requirementsMet; return; end -- If we're here then we were blocked trying to go vertically first so we have to go over first, then up if ( left == buttonColumn ) then left = left + 1; else right = right - 1; end -- Check for blocking talents for i=left, right do if ( TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][i].id ) then -- If there's an id, then throw an error message("Error, this layout is undrawable "..TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][i].id); return; end end -- If we're here we can draw the line left = min(buttonColumn, column); right = max(buttonColumn, column); --TALENT_BRANCH_ARRAY[tier][column].down = requirementsMet; --TALENT_BRANCH_ARRAY[buttonTier][column].up = requirementsMet; for i=tier, buttonTier-1 do TalentFrame.TALENT_BRANCH_ARRAY[i][column].up = requirementsMet; TalentFrame.TALENT_BRANCH_ARRAY[i+1][column].down = requirementsMet; end -- Determine where the arrow goes if ( buttonColumn < column ) then TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][buttonColumn].rightArrow = requirementsMet; else TalentFrame.TALENT_BRANCH_ARRAY[buttonTier][buttonColumn].leftArrow = requirementsMet; endend-- Helper functionsfunction TalentFrame_UpdateTalentPoints(TalentFrame) local talentPoints = GetUnspentTalentPoints(TalentFrame.inspect, TalentFrame.pet, TalentFrame.talentGroup); local unspentPoints = talentPoints - GetGroupPreviewTalentPointsSpent(TalentFrame.pet, TalentFrame.talentGroup); local talentFrameName = TalentFrame:GetName(); _G[talentFrameName.."TalentPointsText"]:SetFormattedText(UNSPENT_TALENT_POINTS, HIGHLIGHT_FONT_COLOR_CODE..unspentPoints..FONT_COLOR_CODE_CLOSE); TalentFrame_ResetBranches(TalentFrame); _G[talentFrameName.."ScrollFrameScrollBarScrollDownButton"]:SetScript("OnClick", _G[talentFrameName.."DownArrow_OnClick"]); return unspentPoints;endfunction SetTalentButtonLocation(button, tier, column) column = ((column - 1) * 63) + INITIAL_TALENT_OFFSET_X; tier = -((tier - 1) * 63) - INITIAL_TALENT_OFFSET_Y; button:SetPoint("TOPLEFT", button:GetParent(), "TOPLEFT", column, tier);endfunction TalentFrame_ResetBranches(TalentFrame) for i=1, MAX_NUM_TALENT_TIERS do for j=1, NUM_TALENT_COLUMNS do TalentFrame.TALENT_BRANCH_ARRAY[i][j].id = nil; TalentFrame.TALENT_BRANCH_ARRAY[i][j].up = 0; TalentFrame.TALENT_BRANCH_ARRAY[i][j].down = 0; TalentFrame.TALENT_BRANCH_ARRAY[i][j].left = 0; TalentFrame.TALENT_BRANCH_ARRAY[i][j].right = 0; TalentFrame.TALENT_BRANCH_ARRAY[i][j].rightArrow = 0; TalentFrame.TALENT_BRANCH_ARRAY[i][j].leftArrow = 0; TalentFrame.TALENT_BRANCH_ARRAY[i][j].topArrow = 0; end endendlocal sortedTabPointsSpentBuf = { };function TalentFrame_UpdateSpecInfoCache(cache, inspect, pet, talentGroup) -- initialize some cache info cache.primaryTabIndex = 0; cache.totalPointsSpent = 0; local preview = GetCVarBool("previewTalents"); local highPointsSpent = 0; local highPointsSpentIndex; local lowPointsSpent = huge; local lowPointsSpentIndex; local numTabs = GetNumTalentTabs(inspect, pet); cache.numTabs = numTabs; for i = 1, MAX_TALENT_TABS do cache[i] = cache[i] or { }; if ( i <= numTabs ) then local name, icon, pointsSpent, background, previewPointsSpent = GetTalentTabInfo(i, inspect, pet, talentGroup); local displayPointsSpent = pointsSpent + previewPointsSpent; -- cache the info we care about cache[i].name = name; cache[i].pointsSpent = displayPointsSpent; cache[i].icon = icon; -- update total points cache.totalPointsSpent = cache.totalPointsSpent + displayPointsSpent; -- update the high and low points spent info if ( displayPointsSpent > highPointsSpent ) then highPointsSpent = displayPointsSpent; highPointsSpentIndex = i; end if ( displayPointsSpent < lowPointsSpent ) then lowPointsSpent = displayPointsSpent; lowPointsSpentIndex = i; end -- initialize the points spent buffer element sortedTabPointsSpentBuf[i] = 0; -- insert the points spent into our buffer in ascending order local insertIndex = i; for j = 1, i, 1 do local currPointsSpent = sortedTabPointsSpentBuf[j]; if ( currPointsSpent > displayPointsSpent ) then insertIndex = j; break; end end for j = i, insertIndex + 1, -1 do sortedTabPointsSpentBuf[j] = sortedTabPointsSpentBuf[j - 1]; end sortedTabPointsSpentBuf[insertIndex] = displayPointsSpent; else cache[i].name = nil; end end if ( highPointsSpentIndex and lowPointsSpentIndex ) then -- now that our points spent buffer is filled, we can compute the mid points spent local midPointsSpentIndex = rshift(numTabs, 1) + 1; local midPointsSpent = sortedTabPointsSpentBuf[midPointsSpentIndex]; -- now let's use our crazy formula to determine which tab is the primary one if ( 3*(midPointsSpent-lowPointsSpent) < 2*(highPointsSpent-lowPointsSpent) ) then cache.primaryTabIndex = highPointsSpentIndex; end endend
I don't how to fix the background and working with 4 talent tress :/
So you think editing Talent.....lua + xml?