commit
e982430c55
|
@ -0,0 +1,11 @@
|
|||
package d2enum
|
||||
|
||||
// Frames of party Buttons
|
||||
const (
|
||||
PartyButtonListeningFrame = iota * 4
|
||||
PartyButtonRelationshipsFrame
|
||||
PartyButtonSeeingFrame
|
||||
PartyButtonCorpsLootingFrame
|
||||
|
||||
PartyButtonNextButtonFrame = 2
|
||||
)
|
|
@ -0,0 +1,21 @@
|
|||
package d2enum
|
||||
|
||||
// PlayersRelationships represents players relationships
|
||||
type PlayersRelationships int
|
||||
|
||||
// Players relationships
|
||||
const (
|
||||
PlayerRelationNeutral PlayersRelationships = iota
|
||||
PlayerRelationFriend
|
||||
PlayerRelationEnemy
|
||||
)
|
||||
|
||||
// determinates a level, which both players should reach to go hostile
|
||||
const (
|
||||
PlayersHostileLevel = 9
|
||||
)
|
||||
|
||||
// determinates max players number for one game
|
||||
const (
|
||||
MaxPlayersInGame = 8
|
||||
)
|
|
@ -246,6 +246,10 @@ const (
|
|||
|
||||
Frame = "/data/global/ui/PANEL/800borderframe.dc6"
|
||||
InventoryCharacterPanel = "/data/global/ui/PANEL/invchar6.DC6"
|
||||
PartyPanel = "/data/global/ui/MENU/party.dc6"
|
||||
PartyButton = "/data/global/ui/MENU/partybuttons.dc6"
|
||||
PartyBoxes = "/data/global/ui/MENU/partyboxes.dc6"
|
||||
PartyBar = "/data/global/ui/MENU/partybar.dc6"
|
||||
HeroStatsPanelStatsPoints = "/data/global/ui/PANEL/skillpoints.dc6"
|
||||
HeroStatsPanelSocket = "/data/global/ui/PANEL/levelsocket.dc6"
|
||||
InventoryWeaponsTab = "/data/global/ui/PANEL/invchar6Tab.DC6"
|
||||
|
|
|
@ -56,6 +56,7 @@ const (
|
|||
ButtonTypeTabBlank ButtonType = 36
|
||||
ButtonTypeBlankQuestBtn ButtonType = 37
|
||||
ButtonTypeAddSkill ButtonType = 38
|
||||
ButtonTypePartyButton ButtonType = 39
|
||||
|
||||
ButtonNoFixedWidth int = -1
|
||||
ButtonNoFixedHeight int = -1
|
||||
|
@ -204,12 +205,16 @@ const (
|
|||
buttonAddSkillSegmentsY = 1
|
||||
buttonAddSkillDisabledFrame = 2
|
||||
|
||||
partyButtonSegmentsX = 1
|
||||
partyButtonSegmentsY = 1
|
||||
partyButtonDisabledFrame = -1
|
||||
|
||||
pressedButtonOffset = 2
|
||||
)
|
||||
|
||||
// nolint:funlen // cant reduce
|
||||
func getButtonLayouts() map[ButtonType]ButtonLayout {
|
||||
return map[ButtonType]ButtonLayout{
|
||||
func getButtonLayouts() map[ButtonType]*ButtonLayout {
|
||||
return map[ButtonType]*ButtonLayout{
|
||||
ButtonTypeWide: {
|
||||
XSegments: buttonWideSegmentsX,
|
||||
YSegments: buttonWideSegmentsY,
|
||||
|
@ -765,6 +770,21 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
|
|||
FixedWidth: ButtonNoFixedWidth,
|
||||
FixedHeight: ButtonNoFixedHeight,
|
||||
},
|
||||
ButtonTypePartyButton: {
|
||||
XSegments: partyButtonSegmentsX,
|
||||
YSegments: partyButtonSegmentsY,
|
||||
DisabledFrame: partyButtonDisabledFrame,
|
||||
DisabledColor: lightGreyAlpha75,
|
||||
TextOffset: buttonWideTextOffset,
|
||||
ResourceName: d2resource.PartyButton,
|
||||
PaletteName: d2resource.PaletteUnits,
|
||||
FontPath: d2resource.FontFormal10,
|
||||
AllowFrameChange: true,
|
||||
HasImage: true,
|
||||
FixedWidth: ButtonNoFixedWidth,
|
||||
FixedHeight: ButtonNoFixedHeight,
|
||||
LabelColor: whiteAlpha100,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -774,7 +794,7 @@ var _ ClickableWidget = &Button{}
|
|||
// Button defines a standard wide UI button
|
||||
type Button struct {
|
||||
*BaseWidget
|
||||
buttonLayout ButtonLayout
|
||||
buttonLayout *ButtonLayout
|
||||
normalSurface d2interface.Surface
|
||||
pressedSurface d2interface.Surface
|
||||
toggledSurface d2interface.Surface
|
||||
|
@ -789,6 +809,38 @@ type Button struct {
|
|||
|
||||
// NewButton creates an instance of Button
|
||||
func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
||||
buttonLayout := getButtonLayouts()[buttonType]
|
||||
|
||||
btn := ui.createButton(buttonLayout, text)
|
||||
|
||||
return btn
|
||||
}
|
||||
|
||||
// NewDefaultButton creates a new button with default settings
|
||||
func (ui *UIManager) NewDefaultButton(path string, frame int) *Button {
|
||||
layout := &ButtonLayout{
|
||||
XSegments: 1,
|
||||
YSegments: 1,
|
||||
DisabledFrame: frame,
|
||||
DisabledColor: whiteAlpha100,
|
||||
ResourceName: path,
|
||||
PaletteName: d2resource.PaletteSky,
|
||||
BaseFrame: frame,
|
||||
Toggleable: true,
|
||||
FontPath: d2resource.Font16,
|
||||
AllowFrameChange: true,
|
||||
HasImage: true,
|
||||
FixedWidth: ButtonNoFixedWidth,
|
||||
FixedHeight: ButtonNoFixedHeight,
|
||||
}
|
||||
|
||||
btn := ui.createButton(layout, "")
|
||||
|
||||
return btn
|
||||
}
|
||||
|
||||
// createButton creates button using input layout and text
|
||||
func (ui *UIManager) createButton(layout *ButtonLayout, text string) *Button {
|
||||
base := NewBaseWidget(ui)
|
||||
base.SetVisible(true)
|
||||
|
||||
|
@ -798,24 +850,23 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
|||
pressed: false,
|
||||
}
|
||||
|
||||
buttonLayout := getButtonLayouts()[buttonType]
|
||||
btn.buttonLayout = buttonLayout
|
||||
lbl := ui.NewLabel(buttonLayout.FontPath, d2resource.PaletteUnits)
|
||||
btn.buttonLayout = layout
|
||||
|
||||
lbl := ui.NewLabel(layout.FontPath, d2resource.PaletteUnits)
|
||||
lbl.SetText(text)
|
||||
lbl.Color[0] = d2util.Color(buttonLayout.LabelColor)
|
||||
lbl.Color[0] = d2util.Color(layout.LabelColor)
|
||||
lbl.Alignment = HorizontalAlignCenter
|
||||
|
||||
buttonSprite, err := ui.NewSprite(buttonLayout.ResourceName, buttonLayout.PaletteName)
|
||||
buttonSprite, err := ui.NewSprite(layout.ResourceName, layout.PaletteName)
|
||||
if err != nil {
|
||||
ui.Error(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
if buttonLayout.FixedWidth > 0 {
|
||||
btn.width = buttonLayout.FixedWidth
|
||||
if layout.FixedWidth > 0 {
|
||||
btn.width = layout.FixedWidth
|
||||
} else {
|
||||
for i := 0; i < buttonLayout.XSegments; i++ {
|
||||
for i := 0; i < layout.XSegments; i++ {
|
||||
w, _, frameSizeErr := buttonSprite.GetFrameSize(i)
|
||||
if frameSizeErr != nil {
|
||||
ui.Error(frameSizeErr.Error())
|
||||
|
@ -826,11 +877,11 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
|||
}
|
||||
}
|
||||
|
||||
if buttonLayout.FixedHeight > 0 {
|
||||
btn.height = buttonLayout.FixedHeight
|
||||
if layout.FixedHeight > 0 {
|
||||
btn.height = layout.FixedHeight
|
||||
} else {
|
||||
for i := 0; i < buttonLayout.YSegments; i++ {
|
||||
_, h, frameSizeErr := buttonSprite.GetFrameSize(i * buttonLayout.YSegments)
|
||||
for i := 0; i < layout.YSegments; i++ {
|
||||
_, h, frameSizeErr := buttonSprite.GetFrameSize(i * layout.YSegments)
|
||||
if frameSizeErr != nil {
|
||||
ui.Error(frameSizeErr.Error())
|
||||
return nil
|
||||
|
@ -849,7 +900,7 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
|
|||
|
||||
ui.addWidget(btn) // important that this comes before prerenderStates!
|
||||
|
||||
btn.prerenderStates(buttonSprite, &buttonLayout, lbl)
|
||||
btn.prerenderStates(buttonSprite, layout, lbl)
|
||||
|
||||
return btn
|
||||
}
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
package d2ui
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
)
|
||||
|
||||
// static check if SwitchableButton implemented widget
|
||||
var _ Widget = &SwitchableButton{}
|
||||
|
||||
// SwitchableButton represents switchable button widget
|
||||
type SwitchableButton struct {
|
||||
*BaseWidget
|
||||
active *Button
|
||||
inactive *Button
|
||||
onActivate func()
|
||||
onDeactivate func()
|
||||
state bool
|
||||
}
|
||||
|
||||
// NewSwitchableButton creates new switchable button
|
||||
func (ui *UIManager) NewSwitchableButton(active, inactive *Button, state bool) *SwitchableButton {
|
||||
base := NewBaseWidget(ui)
|
||||
|
||||
sbtn := &SwitchableButton{
|
||||
BaseWidget: base,
|
||||
active: active,
|
||||
inactive: inactive,
|
||||
state: state,
|
||||
}
|
||||
sbtn.bindManager(ui)
|
||||
sbtn.SetVisible(false)
|
||||
|
||||
sbtn.OnActivated(func() {})
|
||||
sbtn.OnDeactivated(func() {})
|
||||
|
||||
ui.addWidget(sbtn)
|
||||
|
||||
return sbtn
|
||||
}
|
||||
|
||||
// SetVisible sets widget's visibility
|
||||
func (sbtn *SwitchableButton) SetVisible(visible bool) {
|
||||
if !visible {
|
||||
sbtn.active.SetVisible(false)
|
||||
sbtn.inactive.SetVisible(false)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if sbtn.state {
|
||||
sbtn.active.SetVisible(true)
|
||||
sbtn.inactive.SetVisible(false)
|
||||
} else {
|
||||
sbtn.active.SetVisible(false)
|
||||
sbtn.inactive.SetVisible(true)
|
||||
}
|
||||
}
|
||||
|
||||
// OnActivated sets onActivate callback
|
||||
func (sbtn *SwitchableButton) OnActivated(cb func()) {
|
||||
sbtn.active.OnActivated(func() {
|
||||
cb()
|
||||
sbtn.state = false
|
||||
sbtn.SetVisible(sbtn.GetVisible())
|
||||
})
|
||||
}
|
||||
|
||||
// Activate switches widget into active state
|
||||
func (sbtn *SwitchableButton) Activate() {
|
||||
sbtn.onActivate()
|
||||
}
|
||||
|
||||
// OnDeactivated sets onDeactivate callback
|
||||
func (sbtn *SwitchableButton) OnDeactivated(cb func()) {
|
||||
sbtn.inactive.OnActivated(func() {
|
||||
cb()
|
||||
sbtn.state = true
|
||||
sbtn.SetVisible(sbtn.GetVisible())
|
||||
})
|
||||
}
|
||||
|
||||
// Deactivate switch widget to inactive state
|
||||
func (sbtn *SwitchableButton) Deactivate() {
|
||||
sbtn.onDeactivate()
|
||||
}
|
||||
|
||||
// SetState sets button's state
|
||||
func (sbtn *SwitchableButton) SetState(state bool) {
|
||||
sbtn.state = state
|
||||
sbtn.SetVisible(sbtn.GetVisible())
|
||||
}
|
||||
|
||||
// SetActiveTooltip sets tooltip of active button's
|
||||
func (sbtn *SwitchableButton) SetActiveTooltip(tooltip *Tooltip) {
|
||||
sbtn.active.SetTooltip(tooltip)
|
||||
}
|
||||
|
||||
// SetInactiveTooltip sets tooltip of inactive button's
|
||||
func (sbtn *SwitchableButton) SetInactiveTooltip(tooltip *Tooltip) {
|
||||
sbtn.inactive.SetTooltip(tooltip)
|
||||
}
|
||||
|
||||
// SetPosition sets widget's position
|
||||
func (sbtn *SwitchableButton) SetPosition(x, y int) {
|
||||
sbtn.BaseWidget.SetPosition(x, y)
|
||||
sbtn.active.SetPosition(x, y)
|
||||
sbtn.inactive.SetPosition(x, y)
|
||||
}
|
||||
|
||||
// GetSize returns current button's size
|
||||
func (sbtn *SwitchableButton) GetSize() (x, y int) {
|
||||
if sbtn.state {
|
||||
x, y = sbtn.active.GetSize()
|
||||
} else {
|
||||
x, y = sbtn.inactive.GetSize()
|
||||
}
|
||||
|
||||
return x, y
|
||||
}
|
||||
|
||||
// SetEnabled sets button's enabled
|
||||
func (sbtn *SwitchableButton) SetEnabled(enabled bool) {
|
||||
sbtn.active.SetEnabled(enabled)
|
||||
sbtn.inactive.SetEnabled(enabled)
|
||||
}
|
||||
|
||||
// GetEnabled returns true if current switcher position is enabled
|
||||
func (sbtn *SwitchableButton) GetEnabled() bool {
|
||||
if sbtn.state {
|
||||
return sbtn.active.GetEnabled()
|
||||
}
|
||||
|
||||
return sbtn.inactive.GetEnabled()
|
||||
}
|
||||
|
||||
// SetDisabledColor sets switcher's disabled color
|
||||
func (sbtn *SwitchableButton) SetDisabledColor(color uint32) {
|
||||
sbtn.active.buttonLayout.DisabledColor = color
|
||||
sbtn.inactive.buttonLayout.DisabledColor = color
|
||||
}
|
||||
|
||||
// Advance advances widget
|
||||
func (sbtn *SwitchableButton) Advance(_ float64) error {
|
||||
// noop
|
||||
return nil
|
||||
}
|
||||
|
||||
// Render renders widget
|
||||
func (sbtn *SwitchableButton) Render(target d2interface.Surface) {
|
||||
if sbtn.active.GetVisible() {
|
||||
sbtn.active.Render(target)
|
||||
}
|
||||
|
||||
if sbtn.inactive.GetVisible() {
|
||||
sbtn.inactive.Render(target)
|
||||
}
|
||||
}
|
|
@ -223,6 +223,7 @@ func (v *Game) Render(screen d2interface.Surface) {
|
|||
}
|
||||
|
||||
// Advance runs the update logic on the Gameplay screen
|
||||
// nolint:gocyclo // not need to change
|
||||
func (v *Game) Advance(elapsed float64) error {
|
||||
v.soundEngine.Advance(elapsed)
|
||||
|
||||
|
@ -278,6 +279,10 @@ func (v *Game) Advance(elapsed float64) error {
|
|||
|
||||
v.soundEnv.Advance(elapsed)
|
||||
|
||||
if v.gameControls != nil {
|
||||
v.gameControls.PartyPanel.UpdatePlayersList(v.gameClient.Players)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -292,7 +297,7 @@ func (v *Game) bindGameControls() error {
|
|||
var err error
|
||||
v.gameControls, err = d2player.NewGameControls(v.asset, v.renderer, player, v.gameClient.MapEngine,
|
||||
v.escapeMenu, v.mapRenderer, v, v.terminal, v.uiManager, v.keyMap, v.audioProvider, v.logLevel,
|
||||
v.gameClient.IsSinglePlayer())
|
||||
v.gameClient.IsSinglePlayer(), v.gameClient.Players)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -109,6 +109,7 @@ func NewGameControls(
|
|||
audioProvider d2interface.AudioProvider,
|
||||
l d2util.LogLevel,
|
||||
isSinglePlayer bool,
|
||||
players map[string]*d2mapentity.Player,
|
||||
) (*GameControls, error) {
|
||||
var inventoryRecordKey string
|
||||
|
||||
|
@ -172,6 +173,9 @@ func NewGameControls(
|
|||
inventoryRecord := asset.Records.Layout.Inventory[inventoryRecordKey]
|
||||
|
||||
heroStatsPanel := NewHeroStatsPanel(asset, ui, hero.Name(), hero.Class, l, hero.Stats)
|
||||
|
||||
PartyPanel := NewPartyPanel(asset, ui, hero.Name(), l, hero, hero.Stats, players)
|
||||
|
||||
questLog := NewQuestLog(asset, ui, l, audioProvider, hero.Act)
|
||||
|
||||
inventory, err := NewInventory(asset, ui, l, hero.Gold, inventoryRecord)
|
||||
|
@ -204,6 +208,7 @@ func NewGameControls(
|
|||
inventory: inventory,
|
||||
skilltree: skilltree,
|
||||
heroStatsPanel: heroStatsPanel,
|
||||
PartyPanel: PartyPanel,
|
||||
questLog: questLog,
|
||||
HelpOverlay: helpOverlay,
|
||||
keyMap: keyMap,
|
||||
|
@ -273,6 +278,7 @@ type GameControls struct {
|
|||
hud *HUD
|
||||
skilltree *skillTree
|
||||
heroStatsPanel *HeroStatsPanel
|
||||
PartyPanel *PartyPanel
|
||||
questLog *QuestLog
|
||||
HelpOverlay *HelpOverlay
|
||||
bottomMenuRect *d2geom.Rectangle
|
||||
|
@ -359,6 +365,10 @@ func (g *GameControls) OnKeyDown(event d2interface.KeyEvent) bool {
|
|||
g.updateLayout()
|
||||
case d2enum.ToggleInventoryPanel:
|
||||
g.toggleInventoryPanel()
|
||||
case d2enum.TogglePartyPanel:
|
||||
if !g.isSinglePlayer {
|
||||
g.togglePartyPanel()
|
||||
}
|
||||
case d2enum.ToggleSkillTreePanel:
|
||||
g.toggleSkilltreePanel()
|
||||
case d2enum.ToggleCharacterPanel:
|
||||
|
@ -493,6 +503,7 @@ func (g *GameControls) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
|||
}
|
||||
|
||||
g.hud.OnMouseMove(event)
|
||||
g.PartyPanel.OnMouseMove(event)
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -551,6 +562,7 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
|||
|
||||
func (g *GameControls) clearLeftScreenSide() {
|
||||
g.heroStatsPanel.Close()
|
||||
g.PartyPanel.Close()
|
||||
g.questLog.Close()
|
||||
g.hud.skillSelectMenu.ClosePanels()
|
||||
g.hud.miniPanel.SetMovedRight(false)
|
||||
|
@ -604,6 +616,10 @@ func (g *GameControls) toggleHeroStatsPanel() {
|
|||
g.openLeftPanel(g.heroStatsPanel)
|
||||
}
|
||||
|
||||
func (g *GameControls) togglePartyPanel() {
|
||||
g.openLeftPanel(g.PartyPanel)
|
||||
}
|
||||
|
||||
func (g *GameControls) onCloseHeroStatsPanel() {
|
||||
}
|
||||
|
||||
|
@ -665,6 +681,7 @@ func (g *GameControls) Load() {
|
|||
g.inventory.Load()
|
||||
g.skilltree.load()
|
||||
g.heroStatsPanel.Load()
|
||||
g.PartyPanel.Load()
|
||||
g.questLog.Load()
|
||||
g.HelpOverlay.Load()
|
||||
|
||||
|
@ -673,6 +690,7 @@ func (g *GameControls) Load() {
|
|||
|
||||
miniPanelActions := &miniPanelActions{
|
||||
characterToggle: g.toggleHeroStatsPanel,
|
||||
partyToggle: g.togglePartyPanel,
|
||||
inventoryToggle: g.toggleInventoryPanel,
|
||||
skilltreeToggle: g.toggleSkilltreePanel,
|
||||
menuToggle: g.openEscMenu,
|
||||
|
@ -687,6 +705,7 @@ func (g *GameControls) Advance(elapsed float64) error {
|
|||
g.hud.Advance(elapsed)
|
||||
g.inventory.Advance(elapsed)
|
||||
g.questLog.Advance(elapsed)
|
||||
g.PartyPanel.Advance(elapsed)
|
||||
|
||||
if err := g.escapeMenu.Advance(elapsed); err != nil {
|
||||
return err
|
||||
|
@ -714,7 +733,7 @@ func (g *GameControls) updateLayout() {
|
|||
}
|
||||
|
||||
func (g *GameControls) isLeftPanelOpen() bool {
|
||||
return g.heroStatsPanel.IsOpen() || g.questLog.IsOpen() || g.inventory.moveGoldPanel.IsOpen()
|
||||
return g.heroStatsPanel.IsOpen() || g.PartyPanel.IsOpen() || g.questLog.IsOpen() || g.inventory.moveGoldPanel.IsOpen()
|
||||
}
|
||||
|
||||
func (g *GameControls) isRightPanelOpen() bool {
|
||||
|
|
|
@ -0,0 +1,655 @@
|
|||
package d2player
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
const (
|
||||
lightGreen = 0x18ff00ff
|
||||
red = 0xff0000ff
|
||||
lightRed = 0xdb3f3dff
|
||||
orange = 0xffa800ff
|
||||
)
|
||||
|
||||
const ( // for the dc6 frames
|
||||
partyPanelTopLeft = iota
|
||||
partyPanelTopRight
|
||||
partyPanelBottomLeft
|
||||
partyPanelBottomRight
|
||||
)
|
||||
|
||||
const ( // for bar's dc6 frames
|
||||
barLeft = iota
|
||||
barRight
|
||||
)
|
||||
|
||||
const (
|
||||
partyPanelOffsetX, partyPanelOffsetY = 80, 64
|
||||
)
|
||||
|
||||
const (
|
||||
partyPanelCloseButtonX, partyPanelCloseButtonY = 358, 453
|
||||
partyPanelHeroNameX, partyPanelHeroNameY = 180, 80
|
||||
)
|
||||
|
||||
const (
|
||||
buttonSize = 19
|
||||
)
|
||||
|
||||
const (
|
||||
barX, baseBarY = 90, 134
|
||||
relationshipSwitcherX, baseRelationshipSwitcherY = 95, 150
|
||||
listeningSwitcherX, baseListeningSwitcherY = 342, 140
|
||||
seeingSwitcherX, baseSeeingSwitcherY = 365, 140
|
||||
nameLabelX, baseNameLabelY = 115, 144
|
||||
nameTooltipX, baseNameTooltipY = 100, 120
|
||||
classLabelX, baseClassLabelY = 115, 158
|
||||
levelLabelX, baseLevelLabelY = 386, 160
|
||||
inviteAcceptButtonX, baseInviteAcceptButtonY = 265, 147
|
||||
indexOffset = 52
|
||||
)
|
||||
|
||||
// newPartyIndex creates new party index
|
||||
func (s *PartyPanel) newPartyIndex() *partyIndex {
|
||||
result := &partyIndex{
|
||||
asset: s.asset,
|
||||
me: s.me,
|
||||
}
|
||||
|
||||
nameLabel := s.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
||||
result.nameTooltip = s.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteSky, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||
result.name = nameLabel
|
||||
|
||||
classLabel := s.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
||||
result.class = classLabel
|
||||
|
||||
result.nameRect = d2geom.Rectangle{}
|
||||
|
||||
levelLabel := s.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
||||
levelLabel.Alignment = d2ui.HorizontalAlignRight
|
||||
result.level = levelLabel
|
||||
|
||||
relationships := s.createSwitcher(d2enum.PartyButtonRelationshipsFrame)
|
||||
relationships.SetDisabledColor(lightRed)
|
||||
|
||||
result.relationshipsActiveTooltip = s.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteSky, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||
result.relationshipsActiveTooltip.SetText(s.asset.TranslateString("strParty7") + "\n" + s.asset.TranslateString("strParty8"))
|
||||
relationships.SetActiveTooltip(result.relationshipsActiveTooltip)
|
||||
|
||||
result.relationshipsInactiveTooltip = s.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteSky,
|
||||
d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||
result.relationshipsInactiveTooltip.SetText(s.asset.TranslateString("strParty9") + "\n" + s.asset.TranslateString("strParty8"))
|
||||
relationships.SetInactiveTooltip(result.relationshipsInactiveTooltip)
|
||||
|
||||
result.relationshipSwitcher = relationships
|
||||
|
||||
seeing := s.createSwitcher(d2enum.PartyButtonSeeingFrame)
|
||||
|
||||
result.seeingActiveTooltip = s.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteSky, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||
result.seeingActiveTooltip.SetText(s.asset.TranslateString("strParty19"))
|
||||
seeing.SetActiveTooltip(result.seeingActiveTooltip)
|
||||
|
||||
result.seeingInactiveTooltip = s.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteSky, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||
result.seeingInactiveTooltip.SetText(s.asset.TranslateString("strParty22"))
|
||||
seeing.SetInactiveTooltip(result.seeingInactiveTooltip)
|
||||
|
||||
result.seeingSwitcher = seeing
|
||||
|
||||
listening := s.createSwitcher(d2enum.PartyButtonListeningFrame)
|
||||
|
||||
result.listeningActiveTooltip = s.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteSky, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||
result.listeningActiveTooltip.SetText(s.asset.TranslateString("strParty17") + "\n" + s.asset.TranslateString("strParty18"))
|
||||
listening.SetActiveTooltip(result.listeningActiveTooltip)
|
||||
|
||||
result.listeningInactiveTooltip = s.uiManager.NewTooltip(d2resource.Font16, d2resource.PaletteSky, d2ui.TooltipXCenter, d2ui.TooltipYTop)
|
||||
result.listeningInactiveTooltip.SetText(s.asset.TranslateString("strParty11") + "\n" + s.asset.TranslateString("strParty16"))
|
||||
listening.SetInactiveTooltip(result.listeningInactiveTooltip)
|
||||
|
||||
result.listeningSwitcher = listening
|
||||
|
||||
result.inviteAcceptButton = s.uiManager.NewButton(d2ui.ButtonTypePartyButton, s.asset.TranslateString("Invite"))
|
||||
result.inviteAcceptButton.SetVisible(false)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// partyIndex represents a party index
|
||||
type partyIndex struct {
|
||||
asset *d2asset.AssetManager
|
||||
me *d2mapentity.Player
|
||||
|
||||
hero *d2mapentity.Player
|
||||
name *d2ui.Label
|
||||
nameTooltip *d2ui.Tooltip
|
||||
nameRect d2geom.Rectangle
|
||||
class *d2ui.Label
|
||||
level *d2ui.Label
|
||||
relationshipSwitcher *d2ui.SwitchableButton
|
||||
relationshipsActiveTooltip *d2ui.Tooltip
|
||||
relationshipsInactiveTooltip *d2ui.Tooltip
|
||||
seeingSwitcher *d2ui.SwitchableButton
|
||||
seeingActiveTooltip *d2ui.Tooltip
|
||||
seeingInactiveTooltip *d2ui.Tooltip
|
||||
listeningSwitcher *d2ui.SwitchableButton
|
||||
listeningActiveTooltip *d2ui.Tooltip
|
||||
listeningInactiveTooltip *d2ui.Tooltip
|
||||
inviteAcceptButton *d2ui.Button
|
||||
relationships d2enum.PlayersRelationships
|
||||
}
|
||||
|
||||
func (pi *partyIndex) setNameTooltipText() {
|
||||
switch pi.relationships {
|
||||
case d2enum.PlayerRelationNeutral, d2enum.PlayerRelationFriend:
|
||||
pi.nameTooltip.SetText(pi.asset.TranslateString("Party17"))
|
||||
case d2enum.PlayerRelationEnemy:
|
||||
pi.nameTooltip.SetText(pi.asset.TranslateString("Party12"))
|
||||
}
|
||||
}
|
||||
|
||||
// setColor sets appropriate labels' colors
|
||||
func (pi *partyIndex) setColor(relations d2enum.PlayersRelationships) {
|
||||
var color = d2util.Color(white)
|
||||
|
||||
switch relations {
|
||||
case d2enum.PlayerRelationEnemy:
|
||||
color = d2util.Color(red)
|
||||
|
||||
pi.relationshipSwitcher.SetState(false)
|
||||
case d2enum.PlayerRelationFriend:
|
||||
color = d2util.Color(lightGreen)
|
||||
case d2enum.PlayerRelationNeutral:
|
||||
if pi.CanGoHostile() {
|
||||
color = d2util.Color(white)
|
||||
} else {
|
||||
color = d2util.Color(orange)
|
||||
pi.relationshipSwitcher.SetEnabled(false)
|
||||
}
|
||||
}
|
||||
|
||||
pi.name.Color[0] = color
|
||||
pi.class.Color[0] = color
|
||||
pi.level.Color[0] = color
|
||||
}
|
||||
|
||||
// setPositions sets party-index's position to given
|
||||
func (pi *partyIndex) setPositions(idx int) {
|
||||
var w, h int
|
||||
|
||||
pi.name.SetPosition(nameLabelX, baseNameLabelY+indexOffset*idx)
|
||||
pi.nameTooltip.SetPosition(nameTooltipX, baseNameTooltipY+indexOffset*idx)
|
||||
pi.class.SetPosition(classLabelX, baseClassLabelY+indexOffset*idx)
|
||||
pi.level.SetPosition(levelLabelX, baseLevelLabelY+indexOffset*idx)
|
||||
|
||||
w, h1 := pi.class.GetSize()
|
||||
|
||||
_, h = pi.name.GetSize()
|
||||
|
||||
pi.nameRect = d2geom.Rectangle{
|
||||
Left: nameLabelX,
|
||||
Top: baseNameLabelY + idx*indexOffset,
|
||||
Width: w,
|
||||
Height: h + h1,
|
||||
}
|
||||
|
||||
pi.relationshipSwitcher.SetPosition(relationshipSwitcherX, baseRelationshipSwitcherY+indexOffset*idx)
|
||||
_, h = pi.relationshipsActiveTooltip.GetSize()
|
||||
pi.relationshipsActiveTooltip.SetPosition(relationshipSwitcherX+buttonSize, baseRelationshipSwitcherY+idx*indexOffset-h)
|
||||
_, h = pi.relationshipsInactiveTooltip.GetSize()
|
||||
pi.relationshipsInactiveTooltip.SetPosition(relationshipSwitcherX+buttonSize, baseRelationshipSwitcherY+idx*indexOffset-h)
|
||||
|
||||
pi.seeingSwitcher.SetPosition(seeingSwitcherX, baseSeeingSwitcherY+idx*indexOffset)
|
||||
_, h = pi.seeingActiveTooltip.GetSize()
|
||||
pi.seeingActiveTooltip.SetPosition(seeingSwitcherX+buttonSize, baseSeeingSwitcherY+idx*indexOffset-h)
|
||||
_, h = pi.seeingInactiveTooltip.GetSize()
|
||||
pi.seeingInactiveTooltip.SetPosition(seeingSwitcherX+buttonSize, baseSeeingSwitcherY+idx*indexOffset-h)
|
||||
|
||||
pi.listeningSwitcher.SetPosition(listeningSwitcherX, baseListeningSwitcherY+idx*indexOffset)
|
||||
_, h = pi.listeningActiveTooltip.GetSize()
|
||||
pi.listeningActiveTooltip.SetPosition(listeningSwitcherX+buttonSize, baseListeningSwitcherY+idx*indexOffset-h)
|
||||
_, h = pi.listeningInactiveTooltip.GetSize()
|
||||
pi.listeningInactiveTooltip.SetPosition(listeningSwitcherX+buttonSize, baseListeningSwitcherY+idx*indexOffset-h)
|
||||
|
||||
pi.inviteAcceptButton.SetPosition(inviteAcceptButtonX, baseInviteAcceptButtonY+idx*indexOffset)
|
||||
}
|
||||
|
||||
func (pi *partyIndex) CanGoHostile() bool {
|
||||
return pi.hero.Stats.Level >= d2enum.PlayersHostileLevel && pi.me.Stats.Level >= d2enum.PlayersHostileLevel
|
||||
}
|
||||
|
||||
// NewPartyPanel creates a new party panel
|
||||
func NewPartyPanel(asset *d2asset.AssetManager,
|
||||
ui *d2ui.UIManager,
|
||||
heroName string,
|
||||
l d2util.LogLevel,
|
||||
me *d2mapentity.Player,
|
||||
heroState *d2hero.HeroStatsState,
|
||||
players map[string]*d2mapentity.Player) *PartyPanel {
|
||||
log.Print("OpenDiablo2 - Party Panel - development")
|
||||
|
||||
originX := 0
|
||||
originY := 0
|
||||
|
||||
pp := &PartyPanel{
|
||||
asset: asset,
|
||||
uiManager: ui,
|
||||
originX: originX,
|
||||
originY: originY,
|
||||
heroState: heroState,
|
||||
heroName: heroName,
|
||||
labels: &StatsPanelLabels{},
|
||||
barX: barX,
|
||||
barY: baseBarY,
|
||||
players: players,
|
||||
me: me,
|
||||
}
|
||||
|
||||
var partyIndexes [d2enum.MaxPlayersInGame]*partyIndex
|
||||
|
||||
var indexes [d2enum.MaxPlayersInGame]*d2ui.WidgetGroup
|
||||
|
||||
for i := 0; i < d2enum.MaxPlayersInGame; i++ {
|
||||
partyIndexes[i] = pp.newPartyIndex()
|
||||
indexes[i] = pp.uiManager.NewWidgetGroup(d2ui.RenderPriorityHeroStatsPanel)
|
||||
}
|
||||
|
||||
pp.partyIndexes = partyIndexes
|
||||
|
||||
pp.Logger = d2util.NewLogger()
|
||||
pp.Logger.SetLevel(l)
|
||||
pp.Logger.SetPrefix(logPrefix)
|
||||
|
||||
return pp
|
||||
}
|
||||
|
||||
// PartyPanel represents the party panel
|
||||
type PartyPanel struct {
|
||||
asset *d2asset.AssetManager
|
||||
uiManager *d2ui.UIManager
|
||||
panel *d2ui.Sprite
|
||||
bar *d2ui.Sprite
|
||||
heroState *d2hero.HeroStatsState
|
||||
heroName string
|
||||
labels *StatsPanelLabels
|
||||
onCloseCb func()
|
||||
panelGroup *d2ui.WidgetGroup
|
||||
|
||||
partyIndexes [d2enum.MaxPlayersInGame]*partyIndex
|
||||
indexes [d2enum.MaxPlayersInGame]*d2ui.WidgetGroup
|
||||
|
||||
players map[string]*d2mapentity.Player
|
||||
me *d2mapentity.Player
|
||||
|
||||
originX int
|
||||
originY int
|
||||
isOpen bool
|
||||
barX int
|
||||
barY int
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// Load the data for the hero status panel
|
||||
func (s *PartyPanel) Load() {
|
||||
var err error
|
||||
|
||||
var w, h int
|
||||
|
||||
// create widgetGroups
|
||||
s.panelGroup = s.uiManager.NewWidgetGroup(d2ui.RenderPriorityHeroStatsPanel)
|
||||
for i := 0; i < d2enum.MaxPlayersInGame; i++ {
|
||||
s.indexes[i] = s.uiManager.NewWidgetGroup(d2ui.RenderPriorityHeroStatsPanel)
|
||||
}
|
||||
|
||||
// create frame
|
||||
frame := s.uiManager.NewUIFrame(d2ui.FrameLeft)
|
||||
s.panelGroup.AddWidget(frame)
|
||||
|
||||
s.panel, err = s.uiManager.NewSprite(d2resource.PartyPanel, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
s.Error(err.Error())
|
||||
}
|
||||
|
||||
// create panel
|
||||
w, h = frame.GetSize()
|
||||
staticPanel := s.uiManager.NewCustomWidgetCached(s.renderStaticPanelFrames, w, h)
|
||||
s.panelGroup.AddWidget(staticPanel)
|
||||
|
||||
// create close button
|
||||
closeButton := s.uiManager.NewButton(d2ui.ButtonTypeSquareClose, "")
|
||||
closeButton.SetVisible(false)
|
||||
closeButton.SetPosition(partyPanelCloseButtonX, partyPanelCloseButtonY)
|
||||
closeButton.OnActivated(func() { s.Close() })
|
||||
s.panelGroup.AddWidget(closeButton)
|
||||
|
||||
// our name label
|
||||
heroName := s.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
|
||||
heroName.SetText(s.heroName)
|
||||
heroName.SetPosition(partyPanelHeroNameX, partyPanelHeroNameY)
|
||||
heroName.Alignment = d2ui.HorizontalAlignCenter
|
||||
s.panelGroup.AddWidget(heroName)
|
||||
|
||||
// create WidgetGroups of party indexes
|
||||
for n, i := range s.partyIndexes {
|
||||
s.indexes[n].AddWidget(i.name)
|
||||
s.indexes[n].AddWidget(i.class)
|
||||
s.indexes[n].AddWidget(i.relationshipSwitcher)
|
||||
s.indexes[n].AddWidget(i.seeingSwitcher)
|
||||
s.indexes[n].AddWidget(i.listeningSwitcher)
|
||||
s.indexes[n].AddWidget(i.level)
|
||||
s.indexes[n].AddWidget(i.inviteAcceptButton)
|
||||
}
|
||||
|
||||
// create bar
|
||||
s.bar, err = s.uiManager.NewSprite(d2resource.PartyBar, d2resource.PaletteSky)
|
||||
if err != nil {
|
||||
s.Error(err.Error())
|
||||
}
|
||||
|
||||
w, h = s.bar.GetCurrentFrameSize()
|
||||
v := s.uiManager.NewCustomWidget(s.renderBar, w, h)
|
||||
s.panelGroup.AddWidget(v)
|
||||
|
||||
s.setBarPosition()
|
||||
|
||||
s.panelGroup.SetVisible(false)
|
||||
}
|
||||
|
||||
// createSwitcher creates party-panel switcher using frame given
|
||||
func (s *PartyPanel) createSwitcher(frame int) *d2ui.SwitchableButton {
|
||||
active := s.uiManager.NewDefaultButton(d2resource.PartyBoxes, frame)
|
||||
inactive := s.uiManager.NewDefaultButton(d2resource.PartyBoxes, frame+d2enum.PartyButtonNextButtonFrame)
|
||||
switcher := s.uiManager.NewSwitchableButton(active, inactive, true)
|
||||
switcher.SetVisible(false)
|
||||
|
||||
return switcher
|
||||
}
|
||||
|
||||
// IsOpen returns true if the hero status panel is open
|
||||
func (s *PartyPanel) IsOpen() bool {
|
||||
return s.isOpen
|
||||
}
|
||||
|
||||
// Toggle toggles the visibility of the hero status panel
|
||||
func (s *PartyPanel) Toggle() {
|
||||
if s.isOpen {
|
||||
s.Close()
|
||||
} else {
|
||||
s.Open()
|
||||
}
|
||||
}
|
||||
|
||||
// Open opens the hero status panel
|
||||
func (s *PartyPanel) Open() {
|
||||
s.isOpen = true
|
||||
s.panelGroup.SetVisible(true)
|
||||
|
||||
for n, i := range s.indexes {
|
||||
if s.partyIndexes[n].hero != nil {
|
||||
i.SetVisible(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close closed the hero status panel
|
||||
func (s *PartyPanel) Close() {
|
||||
s.isOpen = false
|
||||
s.panelGroup.SetVisible(false)
|
||||
|
||||
for _, i := range s.indexes {
|
||||
i.SetVisible(false)
|
||||
}
|
||||
}
|
||||
|
||||
// SetOnCloseCb the callback run on closing the PartyPanel
|
||||
func (s *PartyPanel) SetOnCloseCb(cb func()) {
|
||||
s.onCloseCb = cb
|
||||
}
|
||||
|
||||
// AddPlayer adds a new player to the party panel
|
||||
func (s *PartyPanel) AddPlayer(player *d2mapentity.Player, relations d2enum.PlayersRelationships) {
|
||||
idx := 0
|
||||
|
||||
// search for free index
|
||||
for n, i := range s.partyIndexes {
|
||||
if i.hero == nil {
|
||||
idx = n
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
s.partyIndexes[idx].hero = player
|
||||
|
||||
s.partyIndexes[idx].name.SetText(player.Name())
|
||||
|
||||
s.partyIndexes[idx].class.SetText(s.asset.TranslateString(player.Class.String()))
|
||||
|
||||
s.partyIndexes[idx].level.SetText(s.asset.TranslateString("Level") + ":" + strconv.Itoa(player.Stats.Level))
|
||||
|
||||
s.partyIndexes[idx].relationships = relations
|
||||
|
||||
s.partyIndexes[idx].setColor(relations)
|
||||
|
||||
s.partyIndexes[idx].setPositions(idx)
|
||||
|
||||
s.partyIndexes[idx].setNameTooltipText()
|
||||
}
|
||||
|
||||
// DeletePlayer deletes player from PartyIndexes
|
||||
func (s *PartyPanel) DeletePlayer(player *d2mapentity.Player) bool {
|
||||
for n, i := range s.partyIndexes {
|
||||
if i.hero == player {
|
||||
s.Debugf("removing player at index %d", n)
|
||||
|
||||
s.partyIndexes[n].hero = nil
|
||||
s.Sort()
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Sort sorts party indexes
|
||||
func (s *PartyPanel) Sort() {
|
||||
var emptySlots []*partyIndex
|
||||
|
||||
var emptySlotsNumbers []int
|
||||
|
||||
var fullSlots []*partyIndex
|
||||
|
||||
var fullSlotsNumbers []int
|
||||
|
||||
// split s.partyIndexes to empty and non-empty
|
||||
for n, i := range s.partyIndexes {
|
||||
if i.hero == nil {
|
||||
emptySlots = append(emptySlots, i)
|
||||
emptySlotsNumbers = append(emptySlotsNumbers, n)
|
||||
} else {
|
||||
fullSlots = append(fullSlots, i)
|
||||
fullSlotsNumbers = append(fullSlotsNumbers, n)
|
||||
}
|
||||
}
|
||||
|
||||
// adds non-empty indexes befor empty indexes
|
||||
for n, i := range fullSlots {
|
||||
s.partyIndexes[n] = i
|
||||
}
|
||||
|
||||
// adds empty indexes
|
||||
for n, i := range emptySlots {
|
||||
s.partyIndexes[len(fullSlots)+n] = i
|
||||
}
|
||||
|
||||
// sorts widget groups
|
||||
var sortedWG [d2enum.MaxPlayersInGame]*d2ui.WidgetGroup
|
||||
// first add non empty WG's
|
||||
for n, i := range fullSlotsNumbers {
|
||||
sortedWG[n] = s.indexes[i]
|
||||
}
|
||||
|
||||
// after that, adds empty WG's
|
||||
for n, i := range emptySlotsNumbers {
|
||||
sortedWG[len(fullSlotsNumbers)+n] = s.indexes[i]
|
||||
}
|
||||
|
||||
// overwrite existing order
|
||||
s.indexes = sortedWG
|
||||
|
||||
// sets appropriate positions
|
||||
for n, i := range s.partyIndexes {
|
||||
if i.hero != nil {
|
||||
i.setPositions(n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IsInPanel returns true if player given already exists in panel
|
||||
func (s *PartyPanel) IsInPanel(player *d2mapentity.Player) bool {
|
||||
for _, i := range s.partyIndexes {
|
||||
if i.hero == player {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsMe returns true if player given is "me"
|
||||
func (s *PartyPanel) IsMe(player *d2mapentity.Player) bool {
|
||||
return player == s.me
|
||||
}
|
||||
|
||||
// setBarPosition sets party-panel bar's position
|
||||
func (s *PartyPanel) setBarPosition() {
|
||||
for n, i := range s.partyIndexes {
|
||||
currentN := n
|
||||
|
||||
if i.hero == nil {
|
||||
s.barX, s.barY = barX, baseBarY+currentN*indexOffset
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdatePanel updates panel indexes with players list
|
||||
func (s *PartyPanel) UpdatePanel() {
|
||||
for _, i := range s.players {
|
||||
if !s.IsInPanel(i) && !s.IsMe(i) {
|
||||
s.AddPlayer(i, d2enum.PlayerRelationNeutral)
|
||||
|
||||
// we need to switch all hidden widgets to be visible
|
||||
// s.Open contains appropriate code to do that.
|
||||
if s.IsOpen() {
|
||||
s.Open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdatePlayersList updates internal players list
|
||||
func (s *PartyPanel) UpdatePlayersList(list map[string]*d2mapentity.Player) {
|
||||
s.players = list
|
||||
}
|
||||
|
||||
// Advance advances panel
|
||||
func (s *PartyPanel) Advance(_ float64) {
|
||||
if !s.IsOpen() {
|
||||
return
|
||||
}
|
||||
|
||||
s.UpdatePanel()
|
||||
}
|
||||
|
||||
// OnMouseMove handles mouse movement events
|
||||
func (s *PartyPanel) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
||||
mx, my := event.X(), event.Y()
|
||||
|
||||
for _, i := range s.partyIndexes {
|
||||
// Mouse over a game control element
|
||||
if i.nameRect.IsInRect(mx, my) {
|
||||
i.nameTooltip.SetVisible(true)
|
||||
} else {
|
||||
i.nameTooltip.SetVisible(false)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// nolint:dupl // see quest_log.go.renderStaticPanelFrames comment
|
||||
func (s *PartyPanel) renderStaticPanelFrames(target d2interface.Surface) {
|
||||
frames := []int{
|
||||
partyPanelTopLeft,
|
||||
partyPanelTopRight,
|
||||
partyPanelBottomRight,
|
||||
partyPanelBottomLeft,
|
||||
}
|
||||
|
||||
currentX := s.originX + partyPanelOffsetX
|
||||
currentY := s.originY + partyPanelOffsetY
|
||||
|
||||
for _, frameIndex := range frames {
|
||||
if err := s.panel.SetCurrentFrame(frameIndex); err != nil {
|
||||
s.Error(err.Error())
|
||||
}
|
||||
|
||||
w, h := s.panel.GetCurrentFrameSize()
|
||||
|
||||
switch frameIndex {
|
||||
case statsPanelTopLeft:
|
||||
s.panel.SetPosition(currentX, currentY+h)
|
||||
currentX += w
|
||||
case statsPanelTopRight:
|
||||
s.panel.SetPosition(currentX, currentY+h)
|
||||
currentY += h
|
||||
case statsPanelBottomRight:
|
||||
s.panel.SetPosition(currentX, currentY+h)
|
||||
case statsPanelBottomLeft:
|
||||
s.panel.SetPosition(currentX-w, currentY+h)
|
||||
}
|
||||
|
||||
s.panel.Render(target)
|
||||
}
|
||||
}
|
||||
|
||||
// renderBar renders party panel's bar
|
||||
func (s *PartyPanel) renderBar(target d2interface.Surface) {
|
||||
frames := []int{
|
||||
barLeft,
|
||||
barRight,
|
||||
}
|
||||
|
||||
currentX := s.originX + s.barX
|
||||
currentY := s.originY + s.barY
|
||||
|
||||
for _, frameIndex := range frames {
|
||||
if err := s.bar.SetCurrentFrame(frameIndex); err != nil {
|
||||
s.Error(err.Error())
|
||||
}
|
||||
|
||||
w, h := s.bar.GetCurrentFrameSize()
|
||||
|
||||
switch frameIndex {
|
||||
case statsPanelTopLeft:
|
||||
s.bar.SetPosition(currentX, currentY)
|
||||
currentX += w
|
||||
case statsPanelTopRight:
|
||||
s.bar.SetPosition(currentX, currentY)
|
||||
currentY += h
|
||||
}
|
||||
|
||||
s.bar.Render(target)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue