OpenDiablo2/d2game/d2player/globeWidget.go

242 lines
5.2 KiB
Go

package d2player
import (
"fmt"
"image"
"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/d2ui"
)
type globeType = int
const (
typeHealthGlobe globeType = iota
typeManaGlobe
)
const (
globeHeight = 80
globeWidth = 80
globeSpriteOffsetX = 28
globeSpriteOffsetY = -5
healthStatusOffsetX = 30
healthStatusOffsetY = -13
manaStatusOffsetX = 7
manaStatusOffsetY = -12
manaGlobeScreenOffsetX = 117
hpLabelX = 15
hpLabelY = 487
manaLabelX = 785
manaLabelY = 487
)
// static check that globeWidget implements Widget
var _ d2ui.Widget = &globeWidget{}
// static check that globeWidget implements ClickableWidget
var _ d2ui.ClickableWidget = &globeWidget{}
type globeFrame struct {
sprite *d2ui.Sprite
offsetX int
offsetY int
idx int
gw *globeWidget
}
func (gf *globeFrame) setFrameIndex() {
if err := gf.sprite.SetCurrentFrame(gf.idx); err != nil {
gf.gw.Error(err.Error())
}
}
func (gf *globeFrame) setPosition(x, y int) {
gf.sprite.SetPosition(x+gf.offsetX, y+gf.offsetY)
}
func newGlobeWidget(ui *d2ui.UIManager,
asset *d2asset.AssetManager,
x, y int,
gtype globeType,
value, valueMax *int,
l d2util.LogLevel) *globeWidget {
var globe, overlap *globeFrame
var tooltipX, tooltipY int
var tooltipTrans string
base := d2ui.NewBaseWidget(ui)
base.SetPosition(x, y)
if gtype == typeHealthGlobe {
globe = &globeFrame{
offsetX: healthStatusOffsetX,
offsetY: healthStatusOffsetY,
idx: frameHealthStatus,
}
overlap = &globeFrame{
offsetX: globeSpriteOffsetX,
offsetY: globeSpriteOffsetY,
idx: frameHealthStatus,
}
tooltipX, tooltipY = hpLabelX, hpLabelY
tooltipTrans = "panelhealth"
} else if gtype == typeManaGlobe {
globe = &globeFrame{
offsetX: manaStatusOffsetX,
offsetY: manaStatusOffsetY,
idx: frameManaStatus,
}
overlap = &globeFrame{
offsetX: rightGlobeOffsetX,
offsetY: rightGlobeOffsetY,
idx: frameRightGlobe,
}
tooltipX, tooltipY = manaLabelX, manaLabelY
tooltipTrans = "panelmana"
}
gw := &globeWidget{
BaseWidget: base,
asset: asset,
value: value,
valueMax: valueMax,
globe: globe,
overlap: overlap,
isTooltipLocked: false,
tooltipX: tooltipX,
tooltipY: tooltipY,
tooltipTrans: tooltipTrans,
}
gw.OnHoverStart(func() {
if !gw.isTooltipLocked {
gw.tooltip.SetVisible(true)
}
})
gw.OnHoverEnd(func() {
if !gw.isTooltipLocked {
gw.tooltip.SetVisible(false)
}
})
gw.Logger = d2util.NewLogger()
gw.Logger.SetLevel(l)
gw.Logger.SetPrefix(logPrefix)
return gw
}
type globeWidget struct {
*d2ui.BaseWidget
asset *d2asset.AssetManager
value *int
valueMax *int
globe *globeFrame
overlap *globeFrame
*d2util.Logger
pressed bool
isTooltipLocked bool
tooltip *d2ui.Tooltip
tooltipX int
tooltipY int
tooltipTrans string
}
func (g *globeWidget) load() {
var err error
g.globe.sprite, err = g.GetManager().NewSprite(d2resource.HealthManaIndicator, d2resource.PaletteSky)
if err != nil {
g.Error(err.Error())
}
g.globe.setFrameIndex()
g.overlap.sprite, err = g.GetManager().NewSprite(d2resource.GameGlobeOverlap, d2resource.PaletteSky)
if err != nil {
g.Error(err.Error())
}
g.overlap.setFrameIndex()
// tooltip
g.tooltip = g.GetManager().NewTooltip(d2resource.Font16, d2resource.PaletteUnits, d2ui.TooltipXLeft, d2ui.TooltipYTop)
g.tooltip.SetPosition(g.tooltipX, g.tooltipY)
g.tooltip.SetBoxEnabled(false)
}
// Render draws the widget to the screen
func (g *globeWidget) Render(target d2interface.Surface) {
valuePercent := float64(*g.value) / float64(*g.valueMax)
barHeight := int(valuePercent * float64(globeHeight))
maskRect := image.Rect(0, globeHeight-barHeight, globeWidth, globeHeight)
g.globe.setPosition(g.GetPosition())
g.globe.sprite.RenderSection(target, maskRect)
g.overlap.setPosition(g.GetPosition())
g.overlap.sprite.Render(target)
}
// Contains is special here as the point of origin is at the lower left corner
// in contrast to any other element which is top left.
func (g *globeWidget) Contains(px, py int) bool {
wx, wy := g.globe.sprite.GetPosition()
width, height := g.globe.sprite.GetSize()
return px >= wx && px <= wx+width && py <= wy && py >= wy-height
}
func (g *globeWidget) updateTooltip() {
// Create and format string from string lookup table.
fmtStr := g.asset.TranslateString(g.tooltipTrans)
strPanel := fmt.Sprintf(fmtStr, *g.value, *g.valueMax)
g.tooltip.SetText(strPanel)
}
func (g *globeWidget) Advance(elapsed float64) error {
g.updateTooltip()
return nil
}
func (g *globeWidget) Activate() {
g.isTooltipLocked = !g.isTooltipLocked
g.tooltip.SetVisible(g.isTooltipLocked)
}
func (g *globeWidget) GetEnabled() bool {
return true
}
func (g *globeWidget) SetEnabled(enable bool) {
// No-op
}
func (g *globeWidget) GetPressed() bool {
return g.pressed
}
func (g *globeWidget) SetPressed(pressed bool) {
g.pressed = pressed
}
func (g *globeWidget) OnActivated(callback func()) {
// No-op
}