1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-16 04:25:23 +00:00

Merge pull request #975 from gucio321/add-skill-buttons

Add-skill buttons
This commit is contained in:
Tim Sarbin 2020-12-16 18:41:28 -05:00 committed by GitHub
commit 27270e7d98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 231 additions and 73 deletions

View File

@ -243,16 +243,18 @@ const (
MinipanelSmall = "/data/global/ui/PANEL/minipanel_s.dc6" MinipanelSmall = "/data/global/ui/PANEL/minipanel_s.dc6"
MinipanelButton = "/data/global/ui/PANEL/minipanelbtn.DC6" MinipanelButton = "/data/global/ui/PANEL/minipanelbtn.DC6"
Frame = "/data/global/ui/PANEL/800borderframe.dc6" Frame = "/data/global/ui/PANEL/800borderframe.dc6"
InventoryCharacterPanel = "/data/global/ui/PANEL/invchar6.DC6" InventoryCharacterPanel = "/data/global/ui/PANEL/invchar6.DC6"
InventoryWeaponsTab = "/data/global/ui/PANEL/invchar6Tab.DC6" HeroStatsPanelStatsPoints = "/data/global/ui/PANEL/skillpoints.dc6"
SkillsPanelAmazon = "/data/global/ui/SPELLS/skltree_a_back.DC6" HeroStatsPanelSocket = "/data/global/ui/PANEL/levelsocket.dc6"
SkillsPanelBarbarian = "/data/global/ui/SPELLS/skltree_b_back.DC6" InventoryWeaponsTab = "/data/global/ui/PANEL/invchar6Tab.DC6"
SkillsPanelDruid = "/data/global/ui/SPELLS/skltree_d_back.DC6" SkillsPanelAmazon = "/data/global/ui/SPELLS/skltree_a_back.DC6"
SkillsPanelAssassin = "/data/global/ui/SPELLS/skltree_i_back.DC6" SkillsPanelBarbarian = "/data/global/ui/SPELLS/skltree_b_back.DC6"
SkillsPanelNecromancer = "/data/global/ui/SPELLS/skltree_n_back.DC6" SkillsPanelDruid = "/data/global/ui/SPELLS/skltree_d_back.DC6"
SkillsPanelPaladin = "/data/global/ui/SPELLS/skltree_p_back.DC6" SkillsPanelAssassin = "/data/global/ui/SPELLS/skltree_i_back.DC6"
SkillsPanelSorcerer = "/data/global/ui/SPELLS/skltree_s_back.DC6" SkillsPanelNecromancer = "/data/global/ui/SPELLS/skltree_n_back.DC6"
SkillsPanelPaladin = "/data/global/ui/SPELLS/skltree_p_back.DC6"
SkillsPanelSorcerer = "/data/global/ui/SPELLS/skltree_s_back.DC6"
GenericSkills = "/data/global/ui/SPELLS/Skillicon.DC6" GenericSkills = "/data/global/ui/SPELLS/Skillicon.DC6"
AmazonSkills = "/data/global/ui/SPELLS/AmSkillicon.DC6" AmazonSkills = "/data/global/ui/SPELLS/AmSkillicon.DC6"

View File

@ -10,28 +10,23 @@ type HeroStatsState struct {
Level int `json:"level"` Level int `json:"level"`
Experience int `json:"experience"` Experience int `json:"experience"`
Vitality int `json:"vitality"`
Energy int `json:"energy"`
Strength int `json:"strength"` Strength int `json:"strength"`
Energy int `json:"energy"`
Dexterity int `json:"dexterity"` Dexterity int `json:"dexterity"`
Vitality int `json:"vitality"`
// there are stats and skills points remaining to add.
StatsPoints int `json:"statsPoints"`
SkillPoints int `json:"skillPoints"`
AttackRating int `json:"attackRating"` Health int `json:"health"`
DefenseRating int `json:"defenseRating"` MaxHealth int `json:"maxHealth"`
Mana int `json:"mana"`
MaxStamina int `json:"maxStamina"` MaxMana int `json:"maxMana"`
Health int `json:"health"` Stamina float64 `json:"-"` // only MaxStamina is saved, Stamina gets reset on entering world
MaxHealth int `json:"maxHealth"` MaxStamina int `json:"maxStamina"`
Mana int `json:"mana"`
MaxMana int `json:"maxMana"`
FireResistance int `json:"fireResistance"`
ColdResistance int `json:"coldResistance"`
LightningResistance int `json:"lightningResistance"`
PoisonResistance int `json:"poisonResistance"`
// values which are not saved/loaded(computed) // values which are not saved/loaded(computed)
Stamina float64 `json:"-"` // only MaxStamina is saved, Stamina gets reset on entering world NextLevelExp int `json:"-"`
NextLevelExp int `json:"-"`
} }
// CreateHeroStatsState generates a running state from a hero stats. // CreateHeroStatsState generates a running state from a hero stats.
@ -44,6 +39,8 @@ func (f *HeroStateFactory) CreateHeroStatsState(heroClass d2enum.Hero, classStat
Dexterity: classStats.InitDex, Dexterity: classStats.InitDex,
Vitality: classStats.InitVit, Vitality: classStats.InitVit,
Energy: classStats.InitEne, Energy: classStats.InitEne,
StatsPoints: 0,
SkillPoints: 0,
MaxHealth: classStats.InitVit * classStats.LifePerVit, MaxHealth: classStats.InitVit * classStats.LifePerVit,
MaxMana: classStats.InitEne * classStats.ManaPerEne, MaxMana: classStats.InitEne * classStats.ManaPerEne,

View File

@ -55,6 +55,7 @@ const (
ButtonTypeSquelchChat ButtonType = 35 ButtonTypeSquelchChat ButtonType = 35
ButtonTypeTabBlank ButtonType = 36 ButtonTypeTabBlank ButtonType = 36
ButtonTypeBlankQuestBtn ButtonType = 37 ButtonTypeBlankQuestBtn ButtonType = 37
ButtonTypeAddSkill ButtonType = 38
ButtonNoFixedWidth int = -1 ButtonNoFixedWidth int = -1
ButtonNoFixedHeight int = -1 ButtonNoFixedHeight int = -1
@ -199,6 +200,10 @@ const (
buttonGoldCoinSegmentsY = 1 buttonGoldCoinSegmentsY = 1
buttonGoldCoinDisabledFrame = -1 buttonGoldCoinDisabledFrame = -1
buttonAddSkillSegmentsX = 1
buttonAddSkillSegmentsY = 1
buttonAddSkillDisabledFrame = 2
pressedButtonOffset = 2 pressedButtonOffset = 2
) )
@ -746,6 +751,20 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
FixedHeight: ButtonNoFixedHeight, FixedHeight: ButtonNoFixedHeight,
LabelColor: whiteAlpha100, LabelColor: whiteAlpha100,
}, },
ButtonTypeAddSkill: {
XSegments: buttonAddSkillSegmentsX,
YSegments: buttonAddSkillSegmentsY,
DisabledFrame: buttonAddSkillDisabledFrame,
DisabledColor: whiteAlpha100,
ResourceName: d2resource.AddSkillButton,
PaletteName: d2resource.PaletteSky,
Toggleable: true,
FontPath: d2resource.Font16,
AllowFrameChange: true,
HasImage: true,
FixedWidth: ButtonNoFixedWidth,
FixedHeight: ButtonNoFixedHeight,
},
} }
} }

View File

@ -398,25 +398,15 @@ func (m *EscapeMenu) OnLoad() {
// OnEscKey is called when the escape key is pressed // OnEscKey is called when the escape key is pressed
func (m *EscapeMenu) OnEscKey() { func (m *EscapeMenu) OnEscKey() {
// note: original D2 returns straight to the game from however deep in the menu we are if m.currentLayout == configureControlsLayoutID {
switch m.currentLayout {
case optionsLayoutID:
m.setLayout(mainLayoutID)
return
case soundOptionsLayoutID,
videoOptionsLayoutID,
automapOptionsLayoutID,
configureControlsLayoutID:
m.setLayout(optionsLayoutID) m.setLayout(optionsLayoutID)
if err := m.keyBindingMenu.Close(); err != nil { if err := m.keyBindingMenu.Close(); err != nil {
m.Errorf("unable to close the configure controls menu: %v", err.Error()) m.Errorf("unable to close the configure controls menu: %v", err.Error())
} }
} else {
return m.close()
} }
m.close()
} }
// SetOnCloseCb sets the callback that is run when close() is called // SetOnCloseCb sets the callback that is run when close() is called

View File

@ -214,7 +214,7 @@ func NewGameControls(
return nil, err return nil, err
} }
skilltree := newSkillTree(hero.Skills, hero.Class, asset, l, ui) skilltree := newSkillTree(hero.Skills, hero.Class, hero.Stats, asset, l, ui)
miniPanel := newMiniPanel(asset, ui, l, isSinglePlayer) miniPanel := newMiniPanel(asset, ui, l, isSinglePlayer)
@ -224,13 +224,9 @@ func NewGameControls(
} }
helpOverlay := NewHelpOverlay(asset, ui, l, keyMap) helpOverlay := NewHelpOverlay(asset, ui, l, keyMap)
hud := NewHUD(asset, ui, hero, miniPanel, actionableRegions, mapEngine, l, mapRenderer)
const blackAlpha50percent = 0x0000007f const blackAlpha50percent = 0x0000007f
hoverLabel := hud.nameLabel
hoverLabel.SetBackgroundColor(d2util.Color(blackAlpha50percent))
gc := &GameControls{ gc := &GameControls{
asset: asset, asset: asset,
ui: ui, ui: ui,
@ -246,7 +242,6 @@ func NewGameControls(
questLog: questLog, questLog: questLog,
HelpOverlay: helpOverlay, HelpOverlay: helpOverlay,
keyMap: keyMap, keyMap: keyMap,
hud: hud,
bottomMenuRect: &d2geom.Rectangle{ bottomMenuRect: &d2geom.Rectangle{
Left: menuBottomRectX, Left: menuBottomRectX,
Top: menuBottomRectY, Top: menuBottomRectY,
@ -271,6 +266,12 @@ func NewGameControls(
isSinglePlayer: isSinglePlayer, isSinglePlayer: isSinglePlayer,
} }
hud := NewHUD(asset, ui, hero, miniPanel, actionableRegions, mapEngine, l, gc, mapRenderer)
gc.hud = hud
hoverLabel := hud.nameLabel
hoverLabel.SetBackgroundColor(d2util.Color(blackAlpha50percent))
gc.heroStatsPanel.SetOnCloseCb(gc.onCloseHeroStatsPanel) gc.heroStatsPanel.SetOnCloseCb(gc.onCloseHeroStatsPanel)
gc.questLog.SetOnCloseCb(gc.onCloseQuestLog) gc.questLog.SetOnCloseCb(gc.onCloseQuestLog)
gc.inventory.SetOnCloseCb(gc.onCloseInventory) gc.inventory.SetOnCloseCb(gc.onCloseInventory)
@ -713,6 +714,9 @@ func (g *GameControls) Load() {
g.questLog.Load() g.questLog.Load()
g.HelpOverlay.Load() g.HelpOverlay.Load()
g.loadAddButtons()
g.setAddButtons()
miniPanelActions := &miniPanelActions{ miniPanelActions := &miniPanelActions{
characterToggle: g.toggleHeroStatsPanel, characterToggle: g.toggleHeroStatsPanel,
inventoryToggle: g.toggleInventoryPanel, inventoryToggle: g.toggleInventoryPanel,
@ -733,6 +737,10 @@ func (g *GameControls) Advance(elapsed float64) error {
return err return err
} }
if g.heroStatsPanel.IsOpen() || g.skilltree.IsOpen() {
g.setAddButtons()
}
return nil return nil
} }
@ -1099,3 +1107,13 @@ func (g *GameControls) bindTerminalCommands(term d2interface.Terminal) error {
return nil return nil
} }
func (g *GameControls) setAddButtons() {
g.hud.addStatsButton.SetEnabled(g.hero.Stats.StatsPoints > 0)
g.hud.addSkillButton.SetEnabled(g.hero.Stats.SkillPoints > 0)
}
func (g *GameControls) loadAddButtons() {
g.hud.addStatsButton.OnActivated(func() { g.toggleHeroStatsPanel() })
g.hud.addSkillButton.OnActivated(func() { g.toggleSkilltreePanel() })
}

View File

@ -9,6 +9,7 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
) )
@ -55,6 +56,15 @@ const (
const ( const (
heroStatsCloseButtonX, heroStatsCloseButtonY = 208, 453 heroStatsCloseButtonX, heroStatsCloseButtonY = 208, 453
addStatSocketOffsetX, addStatSocketOffsetY = -3, 34
)
const (
newStatsRemainingPointsFieldX, newStatsRemainingPointsFieldY = 83, 430
newStatsRemainingPointsLabelX = 92
newStatsRemainingPointsLabel1Y = 411
newStatsRemainingPointsLabel2Y = 418
newStatsRemainingPointsValueX, newStatsRemainingPointsValueY = 188, 411
) )
// PanelText represents text on the panel // PanelText represents text on the panel
@ -113,15 +123,17 @@ func NewHeroStatsPanel(asset *d2asset.AssetManager,
// HeroStatsPanel represents the hero status panel // HeroStatsPanel represents the hero status panel
type HeroStatsPanel struct { type HeroStatsPanel struct {
asset *d2asset.AssetManager asset *d2asset.AssetManager
uiManager *d2ui.UIManager uiManager *d2ui.UIManager
panel *d2ui.Sprite panel *d2ui.Sprite
heroState *d2hero.HeroStatsState heroState *d2hero.HeroStatsState
heroName string heroName string
heroClass d2enum.Hero heroClass d2enum.Hero
labels *StatsPanelLabels labels *StatsPanelLabels
onCloseCb func() onCloseCb func()
panelGroup *d2ui.WidgetGroup panelGroup *d2ui.WidgetGroup
newStatPoints *d2ui.WidgetGroup
remainingPoints *d2ui.Label
originX int originX int
originY int originY int
@ -135,6 +147,7 @@ func (s *HeroStatsPanel) Load() {
var err error var err error
s.panelGroup = s.uiManager.NewWidgetGroup(d2ui.RenderPriorityHeroStatsPanel) s.panelGroup = s.uiManager.NewWidgetGroup(d2ui.RenderPriorityHeroStatsPanel)
s.newStatPoints = s.uiManager.NewWidgetGroup(d2ui.RenderPriorityHeroStatsPanel)
frame := d2ui.NewUIFrame(s.asset, s.uiManager, d2ui.FrameLeft) frame := d2ui.NewUIFrame(s.asset, s.uiManager, d2ui.FrameLeft)
s.panelGroup.AddWidget(frame) s.panelGroup.AddWidget(frame)
@ -154,10 +167,91 @@ func (s *HeroStatsPanel) Load() {
closeButton.OnActivated(func() { s.Close() }) closeButton.OnActivated(func() { s.Close() })
s.panelGroup.AddWidget(closeButton) s.panelGroup.AddWidget(closeButton)
s.loadNewStatPoints()
s.setLayout()
s.initStatValueLabels() s.initStatValueLabels()
s.panelGroup.SetVisible(false) s.panelGroup.SetVisible(false)
} }
func (s *HeroStatsPanel) loadNewStatPoints() {
field, err := s.uiManager.NewSprite(d2resource.HeroStatsPanelStatsPoints, d2resource.PaletteSky)
if err != nil {
s.Error(err.Error())
}
field.SetPosition(newStatsRemainingPointsFieldX, newStatsRemainingPointsFieldY)
s.newStatPoints.AddWidget(field)
label1 := s.uiManager.NewLabel(d2resource.Font6, d2resource.PaletteSky)
label1.SetPosition(newStatsRemainingPointsLabelX, newStatsRemainingPointsLabel1Y)
label1.SetText(s.asset.TranslateString("strchrstat"))
label1.Color[0] = d2util.Color(d2gui.ColorRed)
s.newStatPoints.AddWidget(label1)
label2 := s.uiManager.NewLabel(d2resource.Font6, d2resource.PaletteSky)
label2.SetPosition(newStatsRemainingPointsLabelX, newStatsRemainingPointsLabel2Y)
label2.SetText(s.asset.TranslateString("strchrrema"))
label2.Color[0] = d2util.Color(d2gui.ColorRed)
s.newStatPoints.AddWidget(label2)
s.remainingPoints = s.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
s.remainingPoints.SetText(strconv.Itoa(s.heroState.StatsPoints))
s.remainingPoints.SetPosition(newStatsRemainingPointsValueX, newStatsRemainingPointsValueY)
s.remainingPoints.Alignment = d2ui.HorizontalAlignCenter
s.newStatPoints.AddWidget(s.remainingPoints)
buttons := []struct {
x int
y int
cb func()
}{
{205, 140, func() {
s.heroState.Strength++
}},
{205, 201, func() {
s.heroState.Dexterity++
}},
{205, 286, func() {
s.heroState.Vitality++
}},
{205, 347, func() {
s.heroState.Energy++
}},
}
var socket *d2ui.Sprite
var button *d2ui.Button
for _, i := range buttons {
currentValue := i
socket, err = s.uiManager.NewSprite(d2resource.HeroStatsPanelSocket, d2resource.PaletteSky)
if err != nil {
s.Error(err.Error())
}
socket.SetPosition(i.x+addStatSocketOffsetX, i.y+addStatSocketOffsetY)
s.newStatPoints.AddWidget(socket)
button = s.uiManager.NewButton(d2ui.ButtonTypeAddSkill, d2resource.PaletteSky)
button.SetPosition(i.x, i.y)
button.OnActivated(func() {
currentValue.cb()
s.heroState.StatsPoints--
s.remainingPoints.SetText(strconv.Itoa(s.heroState.StatsPoints))
s.setStatValues()
s.setLayout()
})
s.newStatPoints.AddWidget(button)
}
}
func (s *HeroStatsPanel) setLayout() {
s.newStatPoints.SetVisible(s.heroState.StatsPoints > 0 && s.IsOpen())
}
// IsOpen returns true if the hero status panel is open // IsOpen returns true if the hero status panel is open
func (s *HeroStatsPanel) IsOpen() bool { func (s *HeroStatsPanel) IsOpen() bool {
return s.isOpen return s.isOpen
@ -176,12 +270,14 @@ func (s *HeroStatsPanel) Toggle() {
func (s *HeroStatsPanel) Open() { func (s *HeroStatsPanel) Open() {
s.isOpen = true s.isOpen = true
s.panelGroup.SetVisible(true) s.panelGroup.SetVisible(true)
s.setLayout()
} }
// Close closed the hero status panel // Close closed the hero status panel
func (s *HeroStatsPanel) Close() { func (s *HeroStatsPanel) Close() {
s.isOpen = false s.isOpen = false
s.panelGroup.SetVisible(false) s.panelGroup.SetVisible(false)
s.setLayout()
s.onCloseCb() s.onCloseCb()
} }

View File

@ -70,6 +70,11 @@ const (
whiteAlpha100 = 0xffffffff whiteAlpha100 = 0xffffffff
) )
const (
addStatsButtonX, addStatsButtonY = 206, 561
addSkillButtonX, addSkillButtonY = 563, 561
)
// HUD represents the always visible user interface of the game // HUD represents the always visible user interface of the game
type HUD struct { type HUD struct {
actionableRegions []actionableRegion actionableRegions []actionableRegion
@ -103,7 +108,11 @@ type HUD struct {
widgetLeftSkill *d2ui.CustomWidget widgetLeftSkill *d2ui.CustomWidget
widgetRightSkill *d2ui.CustomWidget widgetRightSkill *d2ui.CustomWidget
panelBackground *d2ui.CustomWidget panelBackground *d2ui.CustomWidget
addStatsButton *d2ui.Button
addSkillButton *d2ui.Button
panelGroup *d2ui.WidgetGroup panelGroup *d2ui.WidgetGroup
gameControls *GameControls
*d2util.Logger *d2util.Logger
} }
@ -116,6 +125,7 @@ func NewHUD(
actionableRegions []actionableRegion, actionableRegions []actionableRegion,
mapEngine *d2mapengine.MapEngine, mapEngine *d2mapengine.MapEngine,
l d2util.LogLevel, l d2util.LogLevel,
gameControls *GameControls,
mapRenderer *d2maprenderer.MapRenderer, mapRenderer *d2maprenderer.MapRenderer,
) *HUD { ) *HUD {
nameLabel := ui.NewLabel(d2resource.Font16, d2resource.PaletteStatic) nameLabel := ui.NewLabel(d2resource.Font16, d2resource.PaletteStatic)
@ -149,6 +159,7 @@ func NewHUD(
zoneChangeText: zoneLabel, zoneChangeText: zoneLabel,
healthGlobe: healthGlobe, healthGlobe: healthGlobe,
manaGlobe: manaGlobe, manaGlobe: manaGlobe,
gameControls: gameControls,
} }
hud.Logger = d2util.NewLogger() hud.Logger = d2util.NewLogger()
@ -177,6 +188,16 @@ func (h *HUD) Load() {
h.loadCustomWidgets() h.loadCustomWidgets()
h.loadUIButtons() h.loadUIButtons()
h.addStatsButton = h.uiManager.NewButton(d2ui.ButtonTypeAddSkill, "")
h.addStatsButton.SetPosition(addStatsButtonX, addStatsButtonY)
h.addStatsButton.SetVisible(false)
h.panelGroup.AddWidget(h.addStatsButton)
h.addSkillButton = h.uiManager.NewButton(d2ui.ButtonTypeAddSkill, "")
h.addSkillButton.SetPosition(addSkillButtonX, addSkillButtonY)
h.addSkillButton.SetVisible(false)
h.panelGroup.AddWidget(h.addSkillButton)
h.panelGroup.SetVisible(true) h.panelGroup.SetVisible(true)
} }

View File

@ -3,6 +3,7 @@ package d2player
import ( import (
"errors" "errors"
"fmt" "fmt"
"strconv"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
@ -56,6 +57,10 @@ const (
frameSelectedTab3Full = 13 frameSelectedTab3Full = 13
) )
const (
remainingPointsLabelX, remainingPointsLabelY = 677, 128
)
const ( const (
skillTreePanelX = 401 skillTreePanelX = 401
skillTreePanelY = 64 skillTreePanelY = 64
@ -87,6 +92,7 @@ type skillTreeHeroTypeResources struct {
func newSkillTree( func newSkillTree(
skills map[int]*d2hero.HeroSkill, skills map[int]*d2hero.HeroSkill,
heroClass d2enum.Hero, heroClass d2enum.Hero,
hero *d2hero.HeroStatsState,
asset *d2asset.AssetManager, asset *d2asset.AssetManager,
l d2util.LogLevel, l d2util.LogLevel,
ui *d2ui.UIManager, ui *d2ui.UIManager,
@ -98,6 +104,7 @@ func newSkillTree(
uiManager: ui, uiManager: ui,
originX: skillTreePanelX, originX: skillTreePanelX,
originY: skillTreePanelY, originY: skillTreePanelY,
stats: hero,
tab: [numTabs]*skillTreeTab{ tab: [numTabs]*skillTreeTab{
{}, {},
{}, {},
@ -114,24 +121,26 @@ func newSkillTree(
} }
type skillTree struct { type skillTree struct {
resources *skillTreeHeroTypeResources resources *skillTreeHeroTypeResources
asset *d2asset.AssetManager asset *d2asset.AssetManager
uiManager *d2ui.UIManager uiManager *d2ui.UIManager
skills map[int]*d2hero.HeroSkill skills map[int]*d2hero.HeroSkill
skillIcons []*skillIcon skillIcons []*skillIcon
heroClass d2enum.Hero heroClass d2enum.Hero
frame *d2ui.UIFrame frame *d2ui.UIFrame
availSPLabel *d2ui.Label availSPLabel *d2ui.Label
closeButton *d2ui.Button closeButton *d2ui.Button
tab [numTabs]*skillTreeTab tab [numTabs]*skillTreeTab
isOpen bool remainingPoints *d2ui.Label
originX int isOpen bool
originY int originX int
selectedTab int originY int
onCloseCb func() selectedTab int
panelGroup *d2ui.WidgetGroup onCloseCb func()
iconGroup *d2ui.WidgetGroup panelGroup *d2ui.WidgetGroup
panel *d2ui.CustomWidget iconGroup *d2ui.WidgetGroup
panel *d2ui.CustomWidget
stats *d2hero.HeroStatsState
*d2util.Logger *d2util.Logger
l d2util.LogLevel l d2util.LogLevel
@ -152,6 +161,12 @@ func (s *skillTree) load() {
s.closeButton.OnActivated(func() { s.Close() }) s.closeButton.OnActivated(func() { s.Close() })
s.panelGroup.AddWidget(s.closeButton) s.panelGroup.AddWidget(s.closeButton)
s.remainingPoints = s.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
s.remainingPoints.SetPosition(remainingPointsLabelX, remainingPointsLabelY)
s.remainingPoints.Alignment = d2ui.HorizontalAlignCenter
s.remainingPoints.SetText(strconv.Itoa(s.stats.SkillPoints))
s.panelGroup.AddWidget(s.remainingPoints)
if err := s.setHeroTypeResourcePath(); err != nil { if err := s.setHeroTypeResourcePath(); err != nil {
s.Error(err.Error()) s.Error(err.Error())
} }