1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-02 09:17:19 -04:00

Merge pull request #15 from gucio321/master

update
This commit is contained in:
gucio321 2020-12-17 15:10:25 +01:00 committed by GitHub
commit 84cac0d181
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 232 additions and 61 deletions

View File

@ -25,7 +25,8 @@ ALL OTHER TRADEMARKS ARE THE PROPERTY OF THEIR RESPECTIVE OWNERS.
## Status ## Status
At the moment (october 2020) the game starts, you can select any character and run around Act1 town. At the moment (december 2020) the game starts, you can select any character and run around Act1 town.
You can also open any of the game's panels.
Much work has been made in the background, but a lot of work still has to be done for the game to be playable. Much work has been made in the background, but a lot of work still has to be done for the game to be playable.
@ -128,6 +129,8 @@ which will be updated over time with new requirements.
![Inventory Window](docs/Inventory.png) ![Inventory Window](docs/Inventory.png)
![Game Panels](docs/game_panels.png)
## Additional Credits ## Additional Credits
- Diablo2 Logo - Diablo2 Logo

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

@ -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())
} }

BIN
docs/game_panels.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB