mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 07:27:19 -05:00
d2player/skilltree: Move every element to widgets
the uiManager now handles every element of the ui, so we don't need to render elements manually in game_controls. Now we can also use widget_groups to simplify handling the opening/closing of the panel.
This commit is contained in:
parent
83acaefea2
commit
622bc832d3
@ -7,6 +7,10 @@ type RenderPriority int
|
||||
const (
|
||||
// RenderPriorityBackground is the first element drawn
|
||||
RenderPriorityBackground RenderPriority = iota
|
||||
// RenderPrioritySkilltree is the priority for the skilltree
|
||||
RenderPrioritySkilltree
|
||||
// RenderPrioritySkilltreeIcon is the priority for the skilltree icons
|
||||
RenderPrioritySkilltreeIcon
|
||||
// RenderPriorityForeground is the last element drawn
|
||||
RenderPriorityForeground
|
||||
)
|
||||
|
@ -370,7 +370,7 @@ func NewGameControls(
|
||||
inputListener: inputListener,
|
||||
mapRenderer: mapRenderer,
|
||||
inventory: NewInventory(asset, ui, inventoryRecord),
|
||||
skilltree: newSkillTree(hero.Skills, hero.Class, asset, renderer, ui, guiManager),
|
||||
skilltree: newSkillTree(hero.Skills, hero.Class, asset, ui),
|
||||
heroStatsPanel: NewHeroStatsPanel(asset, ui, hero.Name(), hero.Class, hero.Stats),
|
||||
HelpOverlay: helpOverlay,
|
||||
hud: hud,
|
||||
@ -773,11 +773,6 @@ func (g *GameControls) renderPanels(target d2interface.Surface) error {
|
||||
g.heroStatsPanel.Render(target)
|
||||
g.inventory.Render(target)
|
||||
|
||||
err := g.skilltree.Render(target)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1015,7 +1010,7 @@ func (g *GameControls) bindLearnSkillsCommand(term d2interface.Terminal) error {
|
||||
}
|
||||
|
||||
if skill, ok := g.hero.Skills[skillDetailRecord.ID]; ok {
|
||||
skill.SkillPoints++;
|
||||
skill.SkillPoints++
|
||||
learnedSkillsCount++
|
||||
} else {
|
||||
skill, skillErr := g.heroState.CreateHeroSkill(1, skillDetailRecord.Skill)
|
||||
|
99
d2game/d2player/skillicon.go
Normal file
99
d2game/d2player/skillicon.go
Normal file
@ -0,0 +1,99 @@
|
||||
package d2player
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
const (
|
||||
skillLabelXOffset = 49
|
||||
skillLabelYOffset = -4
|
||||
|
||||
skillIconXOff = 346
|
||||
skillIconYOff = 59
|
||||
skillIconDistX = 69
|
||||
skillIconDistY = 68
|
||||
)
|
||||
|
||||
type skillIcon struct {
|
||||
*d2ui.BaseWidget
|
||||
lvlLabel *d2ui.Label
|
||||
sprite *d2ui.Sprite
|
||||
skill *d2hero.HeroSkill
|
||||
}
|
||||
|
||||
func newSkillIcon(ui *d2ui.UIManager, baseSprite *d2ui.Sprite, skill *d2hero.HeroSkill) *skillIcon {
|
||||
base := d2ui.NewBaseWidget(ui)
|
||||
label := ui.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
||||
|
||||
x := skillIconXOff + skill.SkillColumn*skillIconDistX
|
||||
y := skillIconYOff + skill.SkillRow*skillIconDistY
|
||||
|
||||
res := &skillIcon{
|
||||
BaseWidget: base,
|
||||
sprite: baseSprite,
|
||||
skill: skill,
|
||||
lvlLabel: label,
|
||||
}
|
||||
|
||||
res.SetPosition(x, y)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (si *skillIcon) SetVisible(visible bool) {
|
||||
si.BaseWidget.SetVisible(visible)
|
||||
si.lvlLabel.SetVisible(visible)
|
||||
}
|
||||
|
||||
func (si *skillIcon) renderSprite(target d2interface.Surface) error {
|
||||
x, y := si.GetPosition()
|
||||
|
||||
if err := si.sprite.SetCurrentFrame(si.skill.IconCel); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if si.skill.SkillPoints == 0 {
|
||||
target.PushSaturation(skillIconGreySat)
|
||||
defer target.Pop()
|
||||
|
||||
target.PushBrightness(skillIconGreyBright)
|
||||
defer target.Pop()
|
||||
}
|
||||
|
||||
si.sprite.SetPosition(x, y)
|
||||
|
||||
if err := si.sprite.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (si *skillIcon) renderSpriteLabel(target d2interface.Surface) error {
|
||||
if si.skill.SkillPoints == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
x, y := si.GetPosition()
|
||||
si.lvlLabel.SetText(strconv.Itoa(si.skill.SkillPoints))
|
||||
si.lvlLabel.SetPosition(x+skillLabelXOffset, y+skillLabelYOffset)
|
||||
|
||||
return si.lvlLabel.Render(target)
|
||||
}
|
||||
|
||||
func (si *skillIcon) Render(target d2interface.Surface) error {
|
||||
if err := si.renderSprite(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return si.renderSpriteLabel(target)
|
||||
}
|
||||
|
||||
func (si *skillIcon) Advance(elapsed float64) error {
|
||||
return nil
|
||||
}
|
@ -3,7 +3,6 @@ package d2player
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
@ -23,14 +22,6 @@ const (
|
||||
availSPLabelX = 677
|
||||
availSPLabelY = 72
|
||||
|
||||
skillIconXOff = 346
|
||||
skillIconYOff = 59
|
||||
skillIconDistX = 69
|
||||
skillIconDistY = 68
|
||||
|
||||
skillLabelXOffset = 49
|
||||
skillLabelYOffset = -4
|
||||
|
||||
skillCloseButtonXLeft = 416
|
||||
skillCloseButtonXMiddle = 501
|
||||
skillCloseButtonXRight = 572
|
||||
@ -83,55 +74,50 @@ type skillTreeTab struct {
|
||||
|
||||
func (st *skillTreeTab) createButton(uiManager *d2ui.UIManager, x, y int) {
|
||||
st.button = uiManager.NewButton(d2ui.ButtonTypeSkillTreeTab, st.buttonText)
|
||||
st.button.SetVisible(false)
|
||||
st.button.SetPosition(x, y)
|
||||
}
|
||||
|
||||
type skillTreeHeroTypeResources struct {
|
||||
skillIcon *d2ui.Sprite
|
||||
skillSprite *d2ui.Sprite
|
||||
skillIconPath string
|
||||
skillPanel *d2ui.Sprite
|
||||
skillPanelPath string
|
||||
}
|
||||
|
||||
type skillTree struct {
|
||||
resources *skillTreeHeroTypeResources
|
||||
asset *d2asset.AssetManager
|
||||
renderer d2interface.Renderer
|
||||
guiManager *d2gui.GuiManager
|
||||
uiManager *d2ui.UIManager
|
||||
layout *d2gui.Layout
|
||||
skills map[int]*d2hero.HeroSkill
|
||||
heroClass d2enum.Hero
|
||||
frame *d2ui.UIFrame
|
||||
availSPLabel *d2ui.Label
|
||||
skillLvlLabel *d2ui.Label
|
||||
closeButton *d2ui.Button
|
||||
tab [numTabs]*skillTreeTab
|
||||
isOpen bool
|
||||
originX int
|
||||
originY int
|
||||
selectedTab int
|
||||
onCloseCb func()
|
||||
resources *skillTreeHeroTypeResources
|
||||
asset *d2asset.AssetManager
|
||||
uiManager *d2ui.UIManager
|
||||
skills map[int]*d2hero.HeroSkill
|
||||
skillIcons []*skillIcon
|
||||
heroClass d2enum.Hero
|
||||
frame *d2ui.UIFrame
|
||||
availSPLabel *d2ui.Label
|
||||
closeButton *d2ui.Button
|
||||
tab [numTabs]*skillTreeTab
|
||||
isOpen bool
|
||||
originX int
|
||||
originY int
|
||||
selectedTab int
|
||||
onCloseCb func()
|
||||
panelGroup *d2ui.WidgetGroup
|
||||
iconGroup *d2ui.WidgetGroup
|
||||
panel *d2ui.CustomWidget
|
||||
}
|
||||
|
||||
func newSkillTree(
|
||||
skills map[int]*d2hero.HeroSkill,
|
||||
heroClass d2enum.Hero,
|
||||
asset *d2asset.AssetManager,
|
||||
renderer d2interface.Renderer,
|
||||
ui *d2ui.UIManager,
|
||||
guiManager *d2gui.GuiManager,
|
||||
) *skillTree {
|
||||
st := &skillTree{
|
||||
skills: skills,
|
||||
heroClass: heroClass,
|
||||
asset: asset,
|
||||
renderer: renderer,
|
||||
uiManager: ui,
|
||||
guiManager: guiManager,
|
||||
originX: skillTreePanelX,
|
||||
originY: skillTreePanelY,
|
||||
skills: skills,
|
||||
heroClass: heroClass,
|
||||
asset: asset,
|
||||
uiManager: ui,
|
||||
originX: skillTreePanelX,
|
||||
originY: skillTreePanelY,
|
||||
tab: [numTabs]*skillTreeTab{
|
||||
{},
|
||||
{},
|
||||
@ -143,16 +129,32 @@ func newSkillTree(
|
||||
}
|
||||
|
||||
func (s *skillTree) load() {
|
||||
s.panelGroup = s.uiManager.NewWidgetGroup(d2ui.RenderPrioritySkilltree)
|
||||
s.iconGroup = s.uiManager.NewWidgetGroup(d2ui.RenderPrioritySkilltreeIcon)
|
||||
|
||||
s.panel = s.uiManager.NewCustomWidget(s.Render)
|
||||
s.panelGroup.AddWidget(s.panel)
|
||||
|
||||
s.frame = d2ui.NewUIFrame(s.asset, s.uiManager, d2ui.FrameRight)
|
||||
s.panelGroup.AddWidget(s.frame)
|
||||
|
||||
s.closeButton = s.uiManager.NewButton(d2ui.ButtonTypeSquareClose, "")
|
||||
s.closeButton.SetVisible(false)
|
||||
s.closeButton.OnActivated(func() { s.Close() })
|
||||
|
||||
s.skillLvlLabel = s.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
||||
s.panelGroup.AddWidget(s.closeButton)
|
||||
|
||||
s.setHeroTypeResourcePath()
|
||||
s.loadForHeroType()
|
||||
|
||||
for _, skill := range s.skills {
|
||||
si := newSkillIcon(s.uiManager, s.resources.skillSprite, skill)
|
||||
s.skillIcons = append(s.skillIcons, si)
|
||||
s.iconGroup.AddWidget(si)
|
||||
}
|
||||
|
||||
s.panelGroup.SetVisible(false)
|
||||
s.setTab(0)
|
||||
s.iconGroup.SetVisible(false)
|
||||
}
|
||||
|
||||
func (s *skillTree) loadForHeroType() {
|
||||
@ -168,21 +170,25 @@ func (s *skillTree) loadForHeroType() {
|
||||
log.Print(err)
|
||||
}
|
||||
|
||||
s.resources.skillIcon = si
|
||||
s.resources.skillSprite = si
|
||||
|
||||
s.tab[firstTab].createButton(s.uiManager, tabButtonX, tabButton0Y)
|
||||
s.tab[firstTab].button.OnActivated(func() { s.setTab(firstTab) })
|
||||
s.panelGroup.AddWidget(s.tab[firstTab].button)
|
||||
|
||||
s.tab[secondTab].createButton(s.uiManager, tabButtonX, tabButton1Y)
|
||||
s.tab[secondTab].button.OnActivated(func() { s.setTab(secondTab) })
|
||||
s.panelGroup.AddWidget(s.tab[secondTab].button)
|
||||
|
||||
s.tab[thirdTab].createButton(s.uiManager, tabButtonX, tabButton2Y)
|
||||
s.tab[thirdTab].button.OnActivated(func() { s.setTab(thirdTab) })
|
||||
s.panelGroup.AddWidget(s.tab[thirdTab].button)
|
||||
|
||||
s.availSPLabel = s.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
||||
s.availSPLabel.SetPosition(availSPLabelX, availSPLabelY)
|
||||
s.availSPLabel.Alignment = d2gui.HorizontalAlignCenter
|
||||
s.availSPLabel.SetText(s.makeTabString("StrSklTree1", "StrSklTree2", "StrSklTree3"))
|
||||
s.panelGroup.AddWidget(s.availSPLabel)
|
||||
}
|
||||
|
||||
type heroTabData struct {
|
||||
@ -340,12 +346,9 @@ func (s *skillTree) Toggle() {
|
||||
// Close the skill tree
|
||||
func (s *skillTree) Close() {
|
||||
s.isOpen = false
|
||||
s.guiManager.SetLayout(nil)
|
||||
s.closeButton.SetVisible(false)
|
||||
|
||||
for i := 0; i < numTabs; i++ {
|
||||
s.tab[i].button.SetVisible(false)
|
||||
}
|
||||
s.panelGroup.SetVisible(false)
|
||||
s.iconGroup.SetVisible(false)
|
||||
|
||||
s.onCloseCb()
|
||||
}
|
||||
@ -353,17 +356,11 @@ func (s *skillTree) Close() {
|
||||
// Open the skill tree
|
||||
func (s *skillTree) Open() {
|
||||
s.isOpen = true
|
||||
if s.layout == nil {
|
||||
s.layout = d2gui.CreateLayout(s.renderer, d2gui.PositionTypeHorizontal, s.asset)
|
||||
}
|
||||
|
||||
s.closeButton.SetVisible(true)
|
||||
s.panelGroup.SetVisible(true)
|
||||
|
||||
for i := 0; i < numTabs; i++ {
|
||||
s.tab[i].button.SetVisible(true)
|
||||
}
|
||||
|
||||
s.guiManager.SetLayout(s.layout)
|
||||
// we only want to enable the icons of our current tab again
|
||||
s.setTab(s.selectedTab)
|
||||
}
|
||||
|
||||
func (s *skillTree) IsOpen() bool {
|
||||
@ -378,6 +375,10 @@ func (s *skillTree) SetOnCloseCb(cb func()) {
|
||||
func (s *skillTree) setTab(tab int) {
|
||||
s.selectedTab = tab
|
||||
s.closeButton.SetPosition(s.tab[tab].closeButtonPosX, skillCloseButtonY)
|
||||
|
||||
for _, si := range s.skillIcons {
|
||||
si.SetVisible(si.skill.SkillPage == tab+1)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *skillTree) renderPanelSegment(
|
||||
@ -512,69 +513,8 @@ func (s *skillTree) renderTab(target d2interface.Surface, tab int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *skillTree) renderSkillIcon(target d2interface.Surface, skill *d2hero.HeroSkill) error {
|
||||
skillIcon := s.resources.skillIcon
|
||||
if err := skillIcon.SetCurrentFrame(skill.IconCel); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
x := skillIconXOff + skill.SkillColumn*skillIconDistX
|
||||
y := skillIconYOff + skill.SkillRow*skillIconDistY
|
||||
|
||||
skillIcon.SetPosition(x, y)
|
||||
|
||||
if skill.SkillPoints == 0 {
|
||||
target.PushSaturation(skillIconGreySat)
|
||||
defer target.Pop()
|
||||
|
||||
target.PushBrightness(skillIconGreyBright)
|
||||
defer target.Pop()
|
||||
}
|
||||
|
||||
skillIcon.RenderNoError(target)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *skillTree) renderSkillIconLabel(target d2interface.Surface, skill *d2hero.HeroSkill) {
|
||||
if skill.SkillPoints == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
s.skillLvlLabel.SetText(strconv.Itoa(skill.SkillPoints))
|
||||
x := skillIconXOff + skill.SkillColumn*skillIconDistX + skillLabelXOffset
|
||||
y := skillIconYOff + skill.SkillRow*skillIconDistY + skillLabelYOffset
|
||||
s.skillLvlLabel.SetPosition(x, y)
|
||||
s.skillLvlLabel.RenderNoError(target)
|
||||
}
|
||||
|
||||
func (s *skillTree) renderSkillIcons(target d2interface.Surface, tab int) error {
|
||||
for idx := range s.skills {
|
||||
skill := s.skills[idx]
|
||||
if skill.SkillPage != tab+1 {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := s.renderSkillIcon(target, skill); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.renderSkillIconLabel(target, skill)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Render the skill tree panel
|
||||
func (s *skillTree) Render(target d2interface.Surface) error {
|
||||
if !s.isOpen {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := s.frame.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.renderTabCommon(target); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -583,9 +523,5 @@ func (s *skillTree) Render(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.renderSkillIcons(target, s.selectedTab); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user