diff --git a/d2common/d2resource/resource_paths.go b/d2common/d2resource/resource_paths.go index a18a196f..dc950ebc 100644 --- a/d2common/d2resource/resource_paths.go +++ b/d2common/d2resource/resource_paths.go @@ -243,16 +243,18 @@ const ( MinipanelSmall = "/data/global/ui/PANEL/minipanel_s.dc6" MinipanelButton = "/data/global/ui/PANEL/minipanelbtn.DC6" - Frame = "/data/global/ui/PANEL/800borderframe.dc6" - InventoryCharacterPanel = "/data/global/ui/PANEL/invchar6.DC6" - InventoryWeaponsTab = "/data/global/ui/PANEL/invchar6Tab.DC6" - SkillsPanelAmazon = "/data/global/ui/SPELLS/skltree_a_back.DC6" - SkillsPanelBarbarian = "/data/global/ui/SPELLS/skltree_b_back.DC6" - SkillsPanelDruid = "/data/global/ui/SPELLS/skltree_d_back.DC6" - SkillsPanelAssassin = "/data/global/ui/SPELLS/skltree_i_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" + Frame = "/data/global/ui/PANEL/800borderframe.dc6" + InventoryCharacterPanel = "/data/global/ui/PANEL/invchar6.DC6" + HeroStatsPanelStatsPoints = "/data/global/ui/PANEL/skillpoints.dc6" + HeroStatsPanelSocket = "/data/global/ui/PANEL/levelsocket.dc6" + InventoryWeaponsTab = "/data/global/ui/PANEL/invchar6Tab.DC6" + SkillsPanelAmazon = "/data/global/ui/SPELLS/skltree_a_back.DC6" + SkillsPanelBarbarian = "/data/global/ui/SPELLS/skltree_b_back.DC6" + SkillsPanelDruid = "/data/global/ui/SPELLS/skltree_d_back.DC6" + SkillsPanelAssassin = "/data/global/ui/SPELLS/skltree_i_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" AmazonSkills = "/data/global/ui/SPELLS/AmSkillicon.DC6" diff --git a/d2core/d2ui/button.go b/d2core/d2ui/button.go index 03b46c8a..b558969a 100644 --- a/d2core/d2ui/button.go +++ b/d2core/d2ui/button.go @@ -200,6 +200,10 @@ const ( buttonGoldCoinSegmentsY = 1 buttonGoldCoinDisabledFrame = -1 + buttonAddSkillSegmentsX = 1 + buttonAddSkillSegmentsY = 1 + buttonAddSkillDisabledFrame = 2 + pressedButtonOffset = 2 ) @@ -748,9 +752,9 @@ func getButtonLayouts() map[ButtonType]ButtonLayout { LabelColor: whiteAlpha100, }, ButtonTypeAddSkill: { - XSegments: 1, - YSegments: 1, - DisabledFrame: 2, + XSegments: buttonAddSkillSegmentsX, + YSegments: buttonAddSkillSegmentsY, + DisabledFrame: buttonAddSkillDisabledFrame, DisabledColor: whiteAlpha100, ResourceName: d2resource.AddSkillButton, PaletteName: d2resource.PaletteSky, diff --git a/d2game/d2player/game_controls.go b/d2game/d2player/game_controls.go index 98fc3d83..f9556fb7 100644 --- a/d2game/d2player/game_controls.go +++ b/d2game/d2player/game_controls.go @@ -715,7 +715,7 @@ func (g *GameControls) Load() { g.HelpOverlay.Load() g.loadAddButtons() - g.SetAddButtons() + g.setAddButtons() miniPanelActions := &miniPanelActions{ characterToggle: g.toggleHeroStatsPanel, @@ -737,6 +737,10 @@ func (g *GameControls) Advance(elapsed float64) error { return err } + if g.heroStatsPanel.IsOpen() || g.skilltree.IsOpen() { + g.setAddButtons() + } + return nil } @@ -1104,7 +1108,7 @@ func (g *GameControls) bindTerminalCommands(term d2interface.Terminal) error { return nil } -func (g *GameControls) SetAddButtons() { +func (g *GameControls) setAddButtons() { g.hud.addStatsButton.SetEnabled(g.hero.Stats.StatsPoints > 0) g.hud.addSkillButton.SetEnabled(g.hero.Stats.SkillPoints > 0) } diff --git a/d2game/d2player/hero_stats_panel.go b/d2game/d2player/hero_stats_panel.go index 9f9cb5c0..8bc889aa 100644 --- a/d2game/d2player/hero_stats_panel.go +++ b/d2game/d2player/hero_stats_panel.go @@ -9,6 +9,7 @@ import ( "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2util" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" + "github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui" ) @@ -55,6 +56,15 @@ const ( const ( 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 @@ -113,15 +123,17 @@ func NewHeroStatsPanel(asset *d2asset.AssetManager, // HeroStatsPanel represents the hero status panel type HeroStatsPanel struct { - asset *d2asset.AssetManager - uiManager *d2ui.UIManager - panel *d2ui.Sprite - heroState *d2hero.HeroStatsState - heroName string - heroClass d2enum.Hero - labels *StatsPanelLabels - onCloseCb func() - panelGroup *d2ui.WidgetGroup + asset *d2asset.AssetManager + uiManager *d2ui.UIManager + panel *d2ui.Sprite + heroState *d2hero.HeroStatsState + heroName string + heroClass d2enum.Hero + labels *StatsPanelLabels + onCloseCb func() + panelGroup *d2ui.WidgetGroup + newStatPoints *d2ui.WidgetGroup + remainingPoints *d2ui.Label originX int originY int @@ -135,6 +147,7 @@ func (s *HeroStatsPanel) Load() { var err error s.panelGroup = s.uiManager.NewWidgetGroup(d2ui.RenderPriorityHeroStatsPanel) + s.newStatPoints = s.uiManager.NewWidgetGroup(d2ui.RenderPriorityHeroStatsPanel) frame := d2ui.NewUIFrame(s.asset, s.uiManager, d2ui.FrameLeft) s.panelGroup.AddWidget(frame) @@ -154,10 +167,91 @@ func (s *HeroStatsPanel) Load() { closeButton.OnActivated(func() { s.Close() }) s.panelGroup.AddWidget(closeButton) + s.loadNewStatPoints() + s.setLayout() + s.initStatValueLabels() 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 func (s *HeroStatsPanel) IsOpen() bool { return s.isOpen @@ -176,12 +270,14 @@ func (s *HeroStatsPanel) Toggle() { func (s *HeroStatsPanel) Open() { s.isOpen = true s.panelGroup.SetVisible(true) + s.setLayout() } // Close closed the hero status panel func (s *HeroStatsPanel) Close() { s.isOpen = false s.panelGroup.SetVisible(false) + s.setLayout() s.onCloseCb() }