Classic Talent Trees

This bundle is marked as pending. It has not been reviewed by a staff member yet.

Overview

Installation

Tutorial

Credits


Overview

Classic Talent Trees is a faithful recreation of the Classic World of Warcraft talent tree system. It is similar to Spellweaver's Talent Kitchen, but is for Lua, has a more extensive UI around it, and sacrifices some customization options for much more convenience and code brevity.

In addition to mimicking the World of Warcraft talent trees, these features are available:
  • Talents with variable talent costs.
  • Talents with requirements from other talent trees.
  • Require total talent points spent to unlock talent.
  • Option to build talent trees bottom-to-top.

New single- or multi-rank talents can be built quickly and easily. You have the option to insert values automatically from code or from ability fields directly into the tooltips. Here is a talent that teaches Starfall to the player's hero:
Lua:
CTT.RegisterTalent({
    name = "Starfall",
    tooltip = "While channeling, calls down waves of falling stars that damage nearby enemy units. Each wave deals !damage! damage. Lasts for !duration! seconds. !cooldown! seconds cooldown.",
    icon = "TalentIcons\\Starfall.blp",
    tree = "Lunar",
    column = 3,
    row = 3,
    --Retrieve values from the ability fields of the linked ability.
    ability = "AEsf",
    values = {
        damage = "Esf1",
        duration = "adur",
        cooldown = "acdn"
    },
    onLearn = function(whichPlayer, talentName, parentTree, oldRank, newRank)
        if newRank > 0 then
            UnitAddAbility(HeroOfPlayer[whichPlayer], FourCC "AEsf")
        else
            UnitRemoveAbility(HeroOfPlayer[whichPlayer], FourCC "AEsf")
        end
    end,
})

You can conveniently use the talent's values in your code:
Lua:
function OnDamage()
    local source = GetEventDamageSource()
    if CTT.HasTalent(source, "Increased Damage") then
        BlzSetEventDamage(GetEventDamage*(1 + CTT.GetValue(source, "Increased Damage", "amount")))
    end
end
This ensures that anytime you change the numbers in your map, all tooltips and constants get updated accordingly.

Other features:
  • Set different talent trees for different players and add talent trees later in the game.
  • Customize talent tree menu texts.
  • Store a player's talent tree to an array. A function to encode that array into a string is not included.

Installation

Copy the ClassicTalentTrees script file into your map. Next, make sure you have all the requirements imported. These are:

RequirementDescription
Total InitializationNeeds no explanation.
Handle TypeAllows ClassicTalentTrees to determine the correct types of the objects passed into it.
Easy Ability Fields
(optional)
Required for linking talents with abilities.

Then, import all the assets and frame definition files needed. These are:

AssetDescription
TalentTreeTemplates.tocThe .toc file loads all the frame definition files. Make sure you keep the empty line at the bottom or it will break!
TalentTree.fdf
TalentTreeBottomBar.fdf
TalentButton.fdf
TalentTooltip.fdf
These are the frade definition files for the various elements of the talent tree menu.
transparentmask.blpImport this one unchanged.
TalentMenuClose.blp
TalentPointsBackdrop.blp
TalentArrow[...].blp
These files are required, but you can use your own textures if you wish.
TalentTreeFade1-4.blpImport these if you want to use the black border around the background artwork.
blackmask.blp
talentTreeBorderYellow.blp
These are referenced in the TalentNavigator.fdf file. You can replace them with different textures if you wish.

Creating a Talent Icon

Creating a Talent

Creating a Values Table

Creating Talent Trees

Customization


Creating a Talent Icon

A talent uses three different frames:
  • The normal icon (without a suffix) is used when a player has unspent talent points and/or has already spent points into that talent, but only if that talent isn't maxed yet.
  • If the talent is maxed, the maxed icon ("<TalentIconPath>Maxed.blp") will be used.
  • The disabled icon ("<TalentIconPath>Disabled.blp") will be used if the talent has no points put into it and the player has no unspent talent points or the requirements for that talent aren't met.
To use the frames from the test map, extract the frame icons that are included in the Assets.zip file and use Button Manager to add the frames to your icons. For the disabled icon, you need to set the saturation of the icon to 0 with an image manipulation tool before adding the frame.

You can use the standard Warcraft 3 enabled and disabled frames instead. To do that, modify the GetTalentIconMaxedPath and GetTalentIconDisabledPath functions in the config to return the correct paths.

Creating a Talent

The CTT.RegisterTalent function creates a talent from the data provided in the data table. The data table has the following fields:

FieldDescription
fourCCThe fourCC code of the ability that is used to retrieve the name, icon, and tooltip of the talent.
name
icon
tooltip
Alternatively, you can enter the name, icon, and tooltip manually with these fields.
treeThe name of the parent tree of the talent.
column
row
The column and row of the talent within its parent tree. Columns and rows start at 1 in the bottom-left corner.
maxPointsThe maximum number of points that can be spent on this talent. Defaults to 1 if not provided.
onLearnAn optional function that is executed whenever the number of points in this talent changes (up or down). The function is called with the arguments (whichPlayer, talentName, parentTree, oldRank, newRank).
requirementAn optional name of a talent that is the requirement for this talent or a table containing multiple requirements. Requirement talents will only have an arrow pointing to the successor talent if they are positioned directly next to the successor on the left or right, directly below it, or two rows below it.
valuesAn optional table with string keys that holds talent data such as damage bonus, duration etc. The values can be auto-inserted into the tooltips. Returns 0, "", or false if the talent rank is zero.
abilityLinks a talent with the ability with the specified fourCC code. By doing so, you can set the entries in the values table to an ability field of that ability. Requires the EasyAbilityFields library.
affectsAn optional fourCC code or table with fourCC codes. Objects added to this table can be displayed in the talent tooltips.


You can run the CTT.RegisterTalent function from anywhere in your code during map initialization before talent trees are initialized.

Creating a Values Table

The values table is a powerful tool to retrieve data from talents as well as insert the values directly into the talent tooltips. The keys of the values table
are strings that should indicate what this value is representing. Example:

Lua:
values = {
    damage = 10,
    duration = 15
}

You can insert the values automatically into the tooltip by using the referenced word surrounded by two exclamation marks:
"Your Curse of Pain deals an additional !damage! damage over !duration! seconds."

The value provided in the values table will be multiplied by the talent's current rank, so, on a 5-rank talent, the tooltip will be:
"Your Curse of Pain deals an additional 15/30/45/60/75 damage over 15/30/45/60/75 seconds."

Increasing the duration with each rank is probably not intended, so we can turn the value into a constant by adding the $ character:
"Your Curse of Pain deals an additional !damage! damage over !duration,$! seconds."

A value can be expressed as a percentage, by adding the percentage symbol (use \x25 instead if you're adding the tooltip via the tooltip field):
"Increases the damage dealt by your Curse of Pain by !damage,%!."

The two characters can be combined by writing !value,%$!.

You can provide a table instead of a number to specify the value of each rank individually:

Lua:
values = {
    damage = {10, 15, 20, 25, 30},
    duration = 15
}

The values do not have to be numbers:

Lua:
values = {
    food = {
        "Homemade Brownie",
        "Creamy Cheesecake",
        "Cinnamon Apple Pie",
        "Chocolate Fudge Cake",
        "Layered Black Forest Cake"
    },
    health = 100,
    cooldown = 180
}

"Creates a !food! that can be consumed to restore !health! health. !cooldown,$! seconds cooldown."

The value can be retrieved for calculations in your code with the CTT.GetValue function:

Lua:
function CreateFood(whichBaker)
    local foodType = CTT.GetValue(whichBaker, "Conjure Pastries", "food")
    local healingAmount = CTT.GetValue(whichBaker, "Conjure Pastries", "health")
    --[...]
end

Values do not have to appear in the tooltips. However, constants can only be declared through a reference in the tooltip with the $ sign.

By linking a talent with an ability, you can retrieve the values directly from the ability fields of that ability:
Lua:
ability = "AHbz"
values = {
    duration = "adur",
    damage = "Hbz2",
    range = "aran"
}

The values will be looked up from the level of the ability equal to the number of points put into the talent.

Creating Talent Trees

To create a talent tree, you need to add it to the TALENT_TREES table in the config. A texture called "TalentTreeBackground<Name>.blp" must be present for the background art to appear. The name is converted, removing all spaces and special characters. Example: "Archer's Skills" -> "ArchersSkills".

Before a talent tree can be shown to a player, you need to add it to that player's list of talent trees with CTT.SetTrees. For example, when player 1 picks a Mage character and player 2 a Hunter character, you want to do:
Lua:
CTT.SetTrees(Player 1, "Fire", "Frost", "Arcane")
CTT.SetTrees(Player 2, "Beast Mastery", "Marksmanship", "Survival")

To show the talent trees to the respective player, you need to do:
Lua:
CTT.Show(whichPlayer)

Customization

Many characteristics of the talent tree menu can be customized in the config, but, for some, you need to edit the fdf-files. Here is a list of UI elements you can customize this way:

ElementHow to customize
Menu Border TextureTalentTree.fdf -> TalentTreeBorder -> BackdropCornerSize / BackdropEdgeFile
Top/Bottom Bar BackdropTalentTree.fdf -> TalentTree[Top/Bottom]Bar -> BackdropBackground
Top/Bottom Bar BorderTalentTree.fdf -> TalentTree[Top/Bottom]Bar -> BackdropCornerSize / BackdropEdgeFile
Talent Navigator BackdropTalentNavigator.fdf -> BackdropBackground
Talent Navigator BorderTalentNavigator.fdf -> BackdropCornerSize / BackdropEdgeFile
Talent Navigator Mouse-Over HighlightTalentTree.fdf -> TalentNavigatorHighlight -> HighlightAlphaFile
Talent Cost IconTalentTooltip.fdf -> TalentTooltipIcon


Test Map Terrain - Seven Blademasters (2000 B.C. version)
Lunar Background Art - Glenn Rane (Hearthstone)
Survival Tree Background Art - Jorge Jacinto
Contents

ClasicTalentTrees (Map)

ClassicTalentTrees (Binary)

TalentTreeAssets (Binary)

Level 26
Joined
Jun 11, 2017
Messages
777
It's pretty cool stuff! However, noticed the next bug:
  • If you learn talent, exit the menu, save the map, and then load it back - the game will load properly, but opening the talent menu will result in a game crash.
  • If you do the same while the talent menu is opened - it will disappear on loading, but still pressing "Talent Menu" will crash the game.
IMO, this is a Blizzard issue with frames, I saw that using the FrameLoad custom function could potentially prevent it.
 
The UI looks good.
I suggest to implement close UI by ESC-Pressing.

Is this for 1 Hero per player?
That is a great idea, thanks!

I'm planning to use this for a map where you play multiple heroes sequentially. I will swap out the talent trees registered to the player as you switch to a new hero. But having multiple talent tree systems for different heroes per player at the same time is not supported currently (but it could be with a few tweaks; just replace the player keys and function arguments with units).
 
It's pretty cool stuff! However, noticed the next bug:
  • If you learn talent, exit the menu, save the map, and then load it back - the game will load properly, but opening the talent menu will result in a game crash.
  • If you do the same while the talent menu is opened - it will disappear on loading, but still pressing "Talent Menu" will crash the game.
IMO, this is a Blizzard issue with frames, I saw that using the FrameLoad custom function could potentially prevent it.

That sounds awfully tedious! Let's just nuke that problem once and for all!
 
Last edited:
Top