mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-12-25 19:46:50 -05:00
lint fixes (#703)
This commit is contained in:
parent
2254e4b2a6
commit
858fa18068
@ -1,10 +1,10 @@
|
||||
package d2dcc
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
)
|
||||
|
||||
const cellsPerRow = 4
|
||||
@ -35,21 +35,22 @@ type DCCDirection struct {
|
||||
}
|
||||
|
||||
// CreateDCCDirection creates an instance of a DCCDirection.
|
||||
func CreateDCCDirection(bm *d2common.BitMuncher,
|
||||
file *DCC) *DCCDirection { //nolint:funlen // Can't reduce
|
||||
func CreateDCCDirection(bm *d2common.BitMuncher, file *DCC) *DCCDirection {
|
||||
var crazyBitTable = []byte{0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 26, 28, 30, 32}
|
||||
|
||||
result := &DCCDirection{}
|
||||
result.OutSizeCoded = int(bm.GetUInt32())
|
||||
result.CompressionFlags = int(bm.GetBits(2)) //nolint:gomnd // binary data
|
||||
result.Variable0Bits = int(crazyBitTable[bm.GetBits(4)]) //nolint:gomnd // binary data
|
||||
result.WidthBits = int(crazyBitTable[bm.GetBits(4)]) //nolint:gomnd // binary data
|
||||
result.HeightBits = int(crazyBitTable[bm.GetBits(4)]) //nolint:gomnd // binary data
|
||||
result.XOffsetBits = int(crazyBitTable[bm.GetBits(4)]) //nolint:gomnd // binary data
|
||||
result.YOffsetBits = int(crazyBitTable[bm.GetBits(4)]) //nolint:gomnd // binary data
|
||||
result.OptionalDataBits = int(crazyBitTable[bm.GetBits(4)]) //nolint:gomnd // binary data
|
||||
result.CodedBytesBits = int(crazyBitTable[bm.GetBits(4)]) //nolint:gomnd // binary data
|
||||
result.Frames = make([]*DCCDirectionFrame, file.FramesPerDirection)
|
||||
result := &DCCDirection{
|
||||
OutSizeCoded: int(bm.GetUInt32()),
|
||||
CompressionFlags: int(bm.GetBits(2)), //nolint:gomnd // binary data
|
||||
Variable0Bits: int(crazyBitTable[bm.GetBits(4)]), //nolint:gomnd // binary data
|
||||
WidthBits: int(crazyBitTable[bm.GetBits(4)]), //nolint:gomnd // binary data
|
||||
HeightBits: int(crazyBitTable[bm.GetBits(4)]), //nolint:gomnd // binary data
|
||||
XOffsetBits: int(crazyBitTable[bm.GetBits(4)]), //nolint:gomnd // binary data
|
||||
YOffsetBits: int(crazyBitTable[bm.GetBits(4)]), //nolint:gomnd // binary data
|
||||
OptionalDataBits: int(crazyBitTable[bm.GetBits(4)]), //nolint:gomnd // binary data
|
||||
CodedBytesBits: int(crazyBitTable[bm.GetBits(4)]), //nolint:gomnd // binary data
|
||||
Frames: make([]*DCCDirectionFrame, file.FramesPerDirection),
|
||||
}
|
||||
|
||||
minx := 100000
|
||||
miny := 100000
|
||||
maxx := -100000
|
||||
@ -81,10 +82,7 @@ func CreateDCCDirection(bm *d2common.BitMuncher,
|
||||
result.RawPixelCodesBitstreamSize = int(bm.GetBits(20)) //nolint:gomnd // binary data
|
||||
}
|
||||
|
||||
// PixelValuesKey
|
||||
paletteEntryCount := 0
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
for paletteEntryCount, i := 0, 0; i < 256; i++ {
|
||||
valid := bm.GetBit() != 0
|
||||
if valid {
|
||||
result.PaletteEntries[paletteEntryCount] = byte(i)
|
||||
@ -132,27 +130,31 @@ func CreateDCCDirection(bm *d2common.BitMuncher,
|
||||
result.PixelBuffer = nil
|
||||
|
||||
// Verify that everything we expected to read was actually read (sanity check)...
|
||||
if equalCellsBitstream.BitsRead() != result.EqualCellsBitstreamSize {
|
||||
log.Panic("Did not read the correct number of bits!")
|
||||
}
|
||||
|
||||
if pixelMaskBitstream.BitsRead() != result.PixelMaskBitstreamSize {
|
||||
log.Panic("Did not read the correct number of bits!")
|
||||
}
|
||||
|
||||
if encodingTypeBitsream.BitsRead() != result.EncodingTypeBitsreamSize {
|
||||
log.Panic("Did not read the correct number of bits!")
|
||||
}
|
||||
|
||||
if rawPixelCodesBitstream.BitsRead() != result.RawPixelCodesBitstreamSize {
|
||||
log.Panic("Did not read the correct number of bits!")
|
||||
}
|
||||
result.verify(equalCellsBitstream, pixelMaskBitstream, encodingTypeBitsream, rawPixelCodesBitstream)
|
||||
|
||||
bm.SkipBits(pixelCodeandDisplacement.BitsRead())
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (v *DCCDirection) verify(equalCellsBitstream, pixelMaskBitstream, encodingTypeBitsream, rawPixelCodesBitstream *d2common.BitMuncher) {
|
||||
if equalCellsBitstream.BitsRead() != v.EqualCellsBitstreamSize {
|
||||
log.Panic("Did not read the correct number of bits!")
|
||||
}
|
||||
|
||||
if pixelMaskBitstream.BitsRead() != v.PixelMaskBitstreamSize {
|
||||
log.Panic("Did not read the correct number of bits!")
|
||||
}
|
||||
|
||||
if encodingTypeBitsream.BitsRead() != v.EncodingTypeBitsreamSize {
|
||||
log.Panic("Did not read the correct number of bits!")
|
||||
}
|
||||
|
||||
if rawPixelCodesBitstream.BitsRead() != v.RawPixelCodesBitstreamSize {
|
||||
log.Panic("Did not read the correct number of bits!")
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:gocognit nolint:gocyclo // Can't reduce
|
||||
func (v *DCCDirection) generateFrames(pcd *d2common.BitMuncher) {
|
||||
pbIdx := 0
|
||||
|
@ -2,12 +2,12 @@ package d2asset
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
|
||||
d2iface "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
@ -114,9 +114,9 @@ func (a *animation) Advance(elapsed float64) error {
|
||||
}
|
||||
|
||||
func (a *animation) renderShadow(target d2iface.Surface) error {
|
||||
//_, height := a.GetFrameBounds()
|
||||
direction := a.directions[a.directionIndex]
|
||||
frame := direction.frames[a.frameIndex]
|
||||
|
||||
target.PushFilter(d2enum.FilterLinear)
|
||||
target.PushTranslation(
|
||||
frame.offsetX,
|
||||
@ -161,8 +161,10 @@ func (a *animation) RenderFromOrigin(target d2iface.Surface, shadow bool) error
|
||||
if shadow {
|
||||
_, height := a.GetFrameBounds()
|
||||
height = int(math.Abs(float64(height)))
|
||||
target.PushTranslation((-height / 2), 0)
|
||||
|
||||
target.PushTranslation(-height/2, 0)
|
||||
defer target.Pop()
|
||||
|
||||
return a.renderShadow(target)
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ type Composite struct {
|
||||
}
|
||||
|
||||
type size struct {
|
||||
Width int
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
|
||||
@ -306,6 +306,7 @@ func (c *Composite) loadCompositeLayer(layerKey, layerValue, animationMode, weap
|
||||
return nil, errors.New("animation not found")
|
||||
}
|
||||
|
||||
// GetSize returns the size of the composite
|
||||
func (c *Composite) GetSize() (w, h int) {
|
||||
c.updateSize()
|
||||
return c.size.Width, c.size.Height
|
||||
|
@ -2,10 +2,10 @@ package d2asset
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
"math"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dcc"
|
||||
d2iface "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
@ -3,11 +3,11 @@ package d2asset
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
"image/color"
|
||||
"strings"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
|
||||
)
|
||||
|
||||
var _ d2interface.Font = &Font{} // Static check to confirm struct conforms to interface
|
||||
|
@ -469,7 +469,6 @@ func (v *SelectHeroClass) onOkButtonClicked() {
|
||||
v.heroNameTextbox.GetText(),
|
||||
v.selectedHero,
|
||||
d2datadict.CharStats[v.selectedHero],
|
||||
v.hardcoreCheckbox.GetCheckState(),
|
||||
)
|
||||
v.navigator.ToCreateGame(gameState.FilePath, d2clientconnectiontype.Local, v.connectionHost)
|
||||
}
|
||||
|
@ -32,40 +32,41 @@ type Panel interface {
|
||||
}
|
||||
|
||||
const (
|
||||
initialMissileID = 59
|
||||
expBarWidth = 120.0
|
||||
staminaBarWidth = 102.0
|
||||
globeHeight = 80
|
||||
globeWidth = 80
|
||||
hoverLabelOuterPad = 5
|
||||
initialMissileID = 59
|
||||
expBarWidth = 120.0
|
||||
staminaBarWidth = 102.0
|
||||
globeHeight = 80
|
||||
globeWidth = 80
|
||||
hoverLabelOuterPad = 5
|
||||
mouseBtnActionsTreshhold = 0.25
|
||||
)
|
||||
|
||||
// GameControls represents the game's controls on the screen
|
||||
type GameControls struct {
|
||||
renderer d2interface.Renderer // TODO: This shouldn't be a dependency
|
||||
hero *d2mapentity.Player
|
||||
mapEngine *d2mapengine.MapEngine
|
||||
mapRenderer *d2maprenderer.MapRenderer
|
||||
uiManager *d2ui.UIManager
|
||||
inventory *Inventory
|
||||
heroStatsPanel *HeroStatsPanel
|
||||
inputListener InputCallbackListener
|
||||
FreeCam bool
|
||||
lastMouseX int
|
||||
lastMouseY int
|
||||
missileID int // ID of missile to create when user right clicks.
|
||||
|
||||
// UI
|
||||
globeSprite *d2ui.Sprite
|
||||
hpManaStatusSprite *d2ui.Sprite
|
||||
mainPanel *d2ui.Sprite
|
||||
menuButton *d2ui.Sprite
|
||||
skillIcon *d2ui.Sprite
|
||||
zoneChangeText *d2ui.Label
|
||||
nameLabel *d2ui.Label
|
||||
runButton *d2ui.Button
|
||||
isZoneTextShown bool
|
||||
actionableRegions []ActionableRegion
|
||||
actionableRegions []ActionableRegion
|
||||
renderer d2interface.Renderer // TODO: This shouldn't be a dependency
|
||||
inputListener InputCallbackListener
|
||||
hero *d2mapentity.Player
|
||||
mapEngine *d2mapengine.MapEngine
|
||||
mapRenderer *d2maprenderer.MapRenderer
|
||||
uiManager *d2ui.UIManager
|
||||
inventory *Inventory
|
||||
heroStatsPanel *HeroStatsPanel
|
||||
lastMouseX int
|
||||
lastMouseY int
|
||||
missileID int
|
||||
globeSprite *d2ui.Sprite
|
||||
hpManaStatusSprite *d2ui.Sprite
|
||||
mainPanel *d2ui.Sprite
|
||||
menuButton *d2ui.Sprite
|
||||
skillIcon *d2ui.Sprite
|
||||
zoneChangeText *d2ui.Label
|
||||
nameLabel *d2ui.Label
|
||||
runButton *d2ui.Button
|
||||
lastLeftBtnActionTime float64
|
||||
lastRightBtnActionTime float64
|
||||
FreeCam bool
|
||||
isZoneTextShown bool
|
||||
}
|
||||
|
||||
type ActionableType int
|
||||
@ -87,6 +88,7 @@ const (
|
||||
rightSkill = ActionableType(iota)
|
||||
)
|
||||
|
||||
// NewGameControls creates a GameControls instance and returns a pointer to it
|
||||
func NewGameControls(
|
||||
renderer d2interface.Renderer,
|
||||
hero *d2mapentity.Player,
|
||||
@ -97,9 +99,13 @@ func NewGameControls(
|
||||
ui *d2ui.UIManager,
|
||||
) (*GameControls, error) {
|
||||
missileID := initialMissileID
|
||||
term.BindAction("setmissile", "set missile id to summon on right click", func(id int) {
|
||||
|
||||
err := term.BindAction("setmissile", "set missile id to summon on right click", func(id int) {
|
||||
missileID = id
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
zoneLabel := ui.NewLabel(d2resource.Font30, d2resource.PaletteUnits)
|
||||
zoneLabel.Alignment = d2gui.HorizontalAlignCenter
|
||||
@ -157,9 +163,11 @@ func NewGameControls(
|
||||
{rightSelec, d2common.Rectangle{Left: 562, Top: 563, Width: 30, Height: 30}},
|
||||
{rightSkill, d2common.Rectangle{Left: 634, Top: 550, Width: 50, Height: 50}},
|
||||
},
|
||||
lastLeftBtnActionTime: 0,
|
||||
lastRightBtnActionTime: 0,
|
||||
}
|
||||
|
||||
err := term.BindAction("freecam", "toggle free camera movement", func() {
|
||||
err = term.BindAction("freecam", "toggle free camera movement", func() {
|
||||
gc.FreeCam = !gc.FreeCam
|
||||
})
|
||||
|
||||
@ -170,6 +178,7 @@ func NewGameControls(
|
||||
return gc, nil
|
||||
}
|
||||
|
||||
// OnKeyRepeat is called to handle repeated key presses
|
||||
func (g *GameControls) OnKeyRepeat(event d2interface.KeyEvent) bool {
|
||||
if g.FreeCam {
|
||||
var moveSpeed float64 = 8
|
||||
@ -209,6 +218,7 @@ func (g *GameControls) OnKeyRepeat(event d2interface.KeyEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// OnKeyDown handles key presses
|
||||
func (g *GameControls) OnKeyDown(event d2interface.KeyEvent) bool {
|
||||
switch event.Key() {
|
||||
case d2enum.KeyEscape:
|
||||
@ -216,6 +226,7 @@ func (g *GameControls) OnKeyDown(event d2interface.KeyEvent) bool {
|
||||
g.inventory.Close()
|
||||
g.heroStatsPanel.Close()
|
||||
g.updateLayout()
|
||||
|
||||
break
|
||||
}
|
||||
case d2enum.KeyI:
|
||||
@ -229,13 +240,11 @@ func (g *GameControls) OnKeyDown(event d2interface.KeyEvent) bool {
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var lastLeftBtnActionTime float64 = 0
|
||||
var lastRightBtnActionTime float64 = 0
|
||||
var mouseBtnActionsTreshhold = 0.25
|
||||
|
||||
// OnMouseButtonRepeat handles repeated mouse clicks
|
||||
func (g *GameControls) OnMouseButtonRepeat(event d2interface.MouseEvent) bool {
|
||||
px, py := g.mapRenderer.ScreenToWorld(event.X(), event.Y())
|
||||
px = float64(int(px*10)) / 10.0
|
||||
@ -245,14 +254,14 @@ func (g *GameControls) OnMouseButtonRepeat(event d2interface.MouseEvent) bool {
|
||||
button := event.Button()
|
||||
isLeft := button == d2enum.MouseButtonLeft
|
||||
isRight := button == d2enum.MouseButtonRight
|
||||
lastLeft := now - lastLeftBtnActionTime
|
||||
lastRight := now - lastRightBtnActionTime
|
||||
lastLeft := now - g.lastLeftBtnActionTime
|
||||
lastRight := now - g.lastRightBtnActionTime
|
||||
inRect := !g.isInActiveMenusRect(event.X(), event.Y())
|
||||
shouldDoLeft := lastLeft >= mouseBtnActionsTreshhold
|
||||
shouldDoRight := lastRight >= mouseBtnActionsTreshhold
|
||||
|
||||
if isLeft && shouldDoLeft && inRect {
|
||||
lastLeftBtnActionTime = now
|
||||
g.lastLeftBtnActionTime = now
|
||||
|
||||
g.inputListener.OnPlayerMove(px, py)
|
||||
|
||||
@ -274,7 +283,7 @@ func (g *GameControls) OnMouseButtonRepeat(event d2interface.MouseEvent) bool {
|
||||
}
|
||||
|
||||
if isRight && shouldDoRight && inRect {
|
||||
lastRightBtnActionTime = now
|
||||
g.lastRightBtnActionTime = now
|
||||
|
||||
g.inputListener.OnPlayerCast(g.missileID, px, py)
|
||||
|
||||
@ -284,6 +293,7 @@ func (g *GameControls) OnMouseButtonRepeat(event d2interface.MouseEvent) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// OnMouseMove handles mouse movement events
|
||||
func (g *GameControls) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
||||
mx, my := event.X(), event.Y()
|
||||
g.lastMouseX = mx
|
||||
@ -301,6 +311,7 @@ func (g *GameControls) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// OnMouseButtonDown handles mouse button presses
|
||||
func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
||||
mx, my := event.X(), event.Y()
|
||||
|
||||
@ -317,7 +328,7 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
||||
py = float64(int(py*10)) / 10.0
|
||||
|
||||
if event.Button() == d2enum.MouseButtonLeft && !g.isInActiveMenusRect(mx, my) {
|
||||
lastLeftBtnActionTime = d2common.Now()
|
||||
g.lastLeftBtnActionTime = d2common.Now()
|
||||
|
||||
g.inputListener.OnPlayerMove(px, py)
|
||||
|
||||
@ -325,7 +336,7 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
||||
}
|
||||
|
||||
if event.Button() == d2enum.MouseButtonRight && !g.isInActiveMenusRect(mx, my) {
|
||||
lastRightBtnActionTime = d2common.Now()
|
||||
g.lastRightBtnActionTime = d2common.Now()
|
||||
|
||||
g.inputListener.OnPlayerCast(g.missileID, px, py)
|
||||
|
||||
@ -335,6 +346,7 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Load loads the resources required for the GameControls
|
||||
func (g *GameControls) Load() {
|
||||
animation, _ := d2asset.LoadAnimation(d2resource.GameGlobeOverlap, d2resource.PaletteSky)
|
||||
g.globeSprite, _ = g.uiManager.NewSprite(animation)
|
||||
@ -376,6 +388,7 @@ func (g *GameControls) onToggleRunButton() {
|
||||
g.hero.SetIsRunning(g.hero.IsRunToggled())
|
||||
}
|
||||
|
||||
// Advance advances the state of the GameControls
|
||||
func (g *GameControls) Advance(elapsed float64) error {
|
||||
g.mapRenderer.Advance(elapsed)
|
||||
return nil
|
||||
@ -385,11 +398,12 @@ func (g *GameControls) updateLayout() {
|
||||
isRightPanelOpen := g.isLeftPanelOpen()
|
||||
isLeftPanelOpen := g.isRightPanelOpen()
|
||||
|
||||
if isRightPanelOpen == isLeftPanelOpen {
|
||||
switch {
|
||||
case isRightPanelOpen == isLeftPanelOpen:
|
||||
g.mapRenderer.ViewportDefault()
|
||||
} else if isRightPanelOpen {
|
||||
case isRightPanelOpen:
|
||||
g.mapRenderer.ViewportToLeft()
|
||||
} else {
|
||||
default:
|
||||
g.mapRenderer.ViewportToRight()
|
||||
}
|
||||
}
|
||||
@ -404,7 +418,7 @@ func (g *GameControls) isRightPanelOpen() bool {
|
||||
return g.inventory.IsOpen()
|
||||
}
|
||||
|
||||
func (g *GameControls) isInActiveMenusRect(px int, py int) bool {
|
||||
func (g *GameControls) isInActiveMenusRect(px, py int) bool {
|
||||
var bottomMenuRect = d2common.Rectangle{Left: 0, Top: 550, Width: 800, Height: 50}
|
||||
|
||||
var leftMenuRect = d2common.Rectangle{Left: 0, Top: 0, Width: 400, Height: 600}
|
||||
@ -427,6 +441,7 @@ func (g *GameControls) isInActiveMenusRect(px int, py int) bool {
|
||||
}
|
||||
|
||||
// TODO: consider caching the panels to single image that is reused.
|
||||
// Render draws the GameControls onto the target
|
||||
func (g *GameControls) Render(target d2interface.Surface) error {
|
||||
for entityIdx := range g.mapEngine.Entities() {
|
||||
entity := (g.mapEngine.Entities())[entityIdx]
|
||||
@ -463,8 +478,13 @@ func (g *GameControls) Render(target d2interface.Surface) error {
|
||||
}
|
||||
}
|
||||
|
||||
g.heroStatsPanel.Render(target)
|
||||
g.inventory.Render(target)
|
||||
if err := g.heroStatsPanel.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := g.inventory.Render(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
width, height := target.GetSize()
|
||||
offset := 0
|
||||
@ -679,14 +699,17 @@ func (g *GameControls) Render(target d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetZoneChangeText sets the zoneChangeText
|
||||
func (g *GameControls) SetZoneChangeText(text string) {
|
||||
g.zoneChangeText.SetText(text)
|
||||
}
|
||||
|
||||
// ShowZoneChangeText shows the zoneChangeText
|
||||
func (g *GameControls) ShowZoneChangeText() {
|
||||
g.isZoneTextShown = true
|
||||
}
|
||||
|
||||
// HideZoneChangeTextAfter hides the zoneChangeText after the given amount of seconds
|
||||
func (g *GameControls) HideZoneChangeTextAfter(delay float64) {
|
||||
time.AfterFunc(time.Duration(delay)*time.Second, func() {
|
||||
g.isZoneTextShown = false
|
||||
|
@ -39,9 +39,6 @@ type StatsPanelLabels struct {
|
||||
Stamina *d2ui.Label
|
||||
}
|
||||
|
||||
// stores all the labels that can change during gameplay(e.g. current level, current hp, mana, etc.)
|
||||
var StatValueLabels = make([]d2ui.Label, 13)
|
||||
|
||||
// HeroStatsPanel represents the hero status panel
|
||||
type HeroStatsPanel struct {
|
||||
uiManager *d2ui.UIManager
|
||||
@ -162,7 +159,7 @@ func (s *HeroStatsPanel) renderStaticMenu(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
w, h = s.frame.GetCurrentFrameSize()
|
||||
_, h = s.frame.GetCurrentFrameSize()
|
||||
|
||||
s.frame.SetPosition(x, s.originY+h)
|
||||
|
||||
@ -177,7 +174,7 @@ func (s *HeroStatsPanel) renderStaticMenu(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
w, h = s.frame.GetCurrentFrameSize()
|
||||
_, h = s.frame.GetCurrentFrameSize()
|
||||
s.frame.SetPosition(x, y+h)
|
||||
|
||||
if err := s.frame.Render(target); err != nil {
|
||||
@ -206,7 +203,7 @@ func (s *HeroStatsPanel) renderStaticMenu(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
w, h = s.frame.GetCurrentFrameSize()
|
||||
_, h = s.frame.GetCurrentFrameSize()
|
||||
|
||||
s.frame.SetPosition(x, y+h)
|
||||
|
||||
@ -239,7 +236,7 @@ func (s *HeroStatsPanel) renderStaticMenu(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
w, h = s.panel.GetCurrentFrameSize()
|
||||
_, h = s.panel.GetCurrentFrameSize()
|
||||
|
||||
s.panel.SetPosition(x, y+h)
|
||||
|
||||
@ -254,7 +251,7 @@ func (s *HeroStatsPanel) renderStaticMenu(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
w, h = s.panel.GetCurrentFrameSize()
|
||||
_, h = s.panel.GetCurrentFrameSize()
|
||||
|
||||
s.panel.SetPosition(x, y+h)
|
||||
|
||||
@ -306,6 +303,7 @@ func (s *HeroStatsPanel) renderStaticMenu(target d2interface.Surface) error {
|
||||
{X: 310, Y: 468, Text: "Poison", Font: d2resource.Font6, AlignCenter: true},
|
||||
{X: 310, Y: 477, Text: "Resistance", Font: d2resource.Font6, AlignCenter: true},
|
||||
}
|
||||
|
||||
for _, textElement := range staticTextLabels {
|
||||
label = s.createTextLabel(textElement)
|
||||
label.Render(target)
|
||||
@ -368,7 +366,7 @@ func (s *HeroStatsPanel) renderStatValueNum(label *d2ui.Label, value int,
|
||||
label.Render(target)
|
||||
}
|
||||
|
||||
func (s *HeroStatsPanel) createStatValueLabel(stat int, x int, y int) *d2ui.Label {
|
||||
func (s *HeroStatsPanel) createStatValueLabel(stat, x, y int) *d2ui.Label {
|
||||
text := strconv.Itoa(stat)
|
||||
return s.createTextLabel(PanelText{X: x, Y: y, Text: text, Font: d2resource.Font16, AlignCenter: true})
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package d2player
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||
@ -13,24 +14,25 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
// Inventory represents the inventory
|
||||
type Inventory struct {
|
||||
uiManager *d2ui.UIManager
|
||||
frame *d2ui.Sprite
|
||||
panel *d2ui.Sprite
|
||||
grid *ItemGrid
|
||||
|
||||
hoverLabel *d2ui.Label
|
||||
hoverX, hoverY int
|
||||
hovering bool
|
||||
|
||||
originX, originY int
|
||||
lastMouseX, lastMouseY int
|
||||
|
||||
isOpen bool
|
||||
uiManager *d2ui.UIManager
|
||||
frame *d2ui.Sprite
|
||||
panel *d2ui.Sprite
|
||||
grid *ItemGrid
|
||||
hoverLabel *d2ui.Label
|
||||
hoverX int
|
||||
hoverY int
|
||||
originX int
|
||||
originY int
|
||||
lastMouseX int
|
||||
lastMouseY int
|
||||
hovering bool
|
||||
isOpen bool
|
||||
}
|
||||
|
||||
// NewInventory creates an inventory instance and returns a pointer to it
|
||||
func NewInventory(ui *d2ui.UIManager, record *d2datadict.InventoryRecord) *Inventory {
|
||||
|
||||
hoverLabel := ui.NewLabel(d2resource.FontFormal11, d2resource.PaletteStatic)
|
||||
hoverLabel.Alignment = d2gui.HorizontalAlignCenter
|
||||
|
||||
@ -44,22 +46,27 @@ func NewInventory(ui *d2ui.UIManager, record *d2datadict.InventoryRecord) *Inven
|
||||
}
|
||||
}
|
||||
|
||||
// IsOpen returns true if the inventory is open
|
||||
func (g *Inventory) IsOpen() bool {
|
||||
return g.isOpen
|
||||
}
|
||||
|
||||
// Toggle negates the open state of the inventory
|
||||
func (g *Inventory) Toggle() {
|
||||
g.isOpen = !g.isOpen
|
||||
}
|
||||
|
||||
// Open opens the inventory
|
||||
func (g *Inventory) Open() {
|
||||
g.isOpen = true
|
||||
}
|
||||
|
||||
// Close closes the inventory
|
||||
func (g *Inventory) Close() {
|
||||
g.isOpen = false
|
||||
}
|
||||
|
||||
// Load loads the resources required by the inventory
|
||||
func (g *Inventory) Load() {
|
||||
animation, _ := d2asset.LoadAnimation(d2resource.Frame, d2resource.PaletteSky)
|
||||
g.frame, _ = g.uiManager.NewSprite(animation)
|
||||
@ -71,9 +78,10 @@ func (g *Inventory) Load() {
|
||||
diablo2item.NewItem("rin", "Steel", "of Shock").Identify(),
|
||||
diablo2item.NewItem("jav").Identify(),
|
||||
diablo2item.NewItem("buc").Identify(),
|
||||
//diablo2item.NewItem("Arctic Furs", "qui"),
|
||||
// diablo2item.NewItem("Arctic Furs", "qui"),
|
||||
// TODO: Load the player's actual items
|
||||
}
|
||||
|
||||
g.grid.ChangeEquippedSlot(d2enum.EquippedSlotLeftArm, diablo2item.NewItem("wnd"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.EquippedSlotRightArm, diablo2item.NewItem("buc"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.EquippedSlotHead, diablo2item.NewItem("crn"))
|
||||
@ -85,9 +93,14 @@ func (g *Inventory) Load() {
|
||||
g.grid.ChangeEquippedSlot(d2enum.EquippedSlotRightHand, diablo2item.NewItem("rin"))
|
||||
g.grid.ChangeEquippedSlot(d2enum.EquippedSlotNeck, diablo2item.NewItem("amu"))
|
||||
// TODO: Load the player's actual items
|
||||
g.grid.Add(items...)
|
||||
|
||||
_, err := g.grid.Add(items...)
|
||||
if err != nil {
|
||||
fmt.Printf("could not add items to the inventory, err: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Render draws the inventory onto the given surface
|
||||
func (g *Inventory) Render(target d2interface.Surface) error {
|
||||
if !g.isOpen {
|
||||
return nil
|
||||
@ -194,7 +207,7 @@ func (g *Inventory) Render(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
w, h = g.panel.GetCurrentFrameSize()
|
||||
_, h = g.panel.GetCurrentFrameSize()
|
||||
|
||||
g.panel.SetPosition(x, y+h)
|
||||
|
||||
@ -209,7 +222,7 @@ func (g *Inventory) Render(target d2interface.Surface) error {
|
||||
return err
|
||||
}
|
||||
|
||||
w, h = g.panel.GetCurrentFrameSize()
|
||||
_, h = g.panel.GetCurrentFrameSize()
|
||||
g.panel.SetPosition(x, y+h)
|
||||
|
||||
if err := g.panel.Render(target); err != nil {
|
||||
|
@ -2,8 +2,8 @@ package d2player
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
@ -15,6 +15,7 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2inventory"
|
||||
)
|
||||
|
||||
// PlayerState stores the state of the player
|
||||
type PlayerState struct {
|
||||
HeroName string `json:"heroName"`
|
||||
HeroType d2enum.Hero `json:"heroType"`
|
||||
@ -22,38 +23,46 @@ type PlayerState struct {
|
||||
Act int `json:"act"`
|
||||
FilePath string `json:"-"`
|
||||
Equipment d2inventory.CharacterEquipment `json:"equipment"`
|
||||
Stats *d2hero.HeroStatsState `json:"stats"`
|
||||
Stats *d2hero.HeroStatsState `json:"stats"`
|
||||
X float64 `json:"x"`
|
||||
Y float64 `json:"y"`
|
||||
}
|
||||
|
||||
// HasGameStates returns true if the player has any previously saved game
|
||||
func HasGameStates() bool {
|
||||
basePath, _ := getGameBaseSavePath()
|
||||
files, _ := ioutil.ReadDir(basePath)
|
||||
|
||||
return len(files) > 0
|
||||
}
|
||||
|
||||
// GetAllPlayerStates returns all player saves
|
||||
func GetAllPlayerStates() []*PlayerState {
|
||||
basePath, _ := getGameBaseSavePath()
|
||||
files, _ := ioutil.ReadDir(basePath)
|
||||
result := make([]*PlayerState, 0)
|
||||
|
||||
for _, file := range files {
|
||||
fileName := file.Name()
|
||||
if file.IsDir() || len(fileName) < 5 || strings.ToLower(fileName[len(fileName)-4:]) != ".od2" {
|
||||
continue
|
||||
}
|
||||
|
||||
gameState := LoadPlayerState(path.Join(basePath, file.Name()))
|
||||
if gameState == nil || gameState.HeroType == d2enum.HeroNone {
|
||||
// temporarily loading default class stats if the character was created before saving stats was introduced
|
||||
// to be removed in the future
|
||||
continue
|
||||
// temporarily loading default class stats if the character was created before saving stats was introduced
|
||||
// to be removed in the future
|
||||
} else if gameState.Stats == nil {
|
||||
gameState.Stats = d2hero.CreateHeroStatsState(gameState.HeroType, d2datadict.CharStats[gameState.HeroType])
|
||||
gameState.Save()
|
||||
if err := gameState.Save(); err != nil {
|
||||
fmt.Printf("failed to save game state!, err: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
result = append(result, gameState)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@ -63,33 +72,41 @@ func CreateTestGameState() *PlayerState {
|
||||
return result
|
||||
}
|
||||
|
||||
func LoadPlayerState(path string) *PlayerState {
|
||||
strData, err := ioutil.ReadFile(path)
|
||||
// LoadPlayerState loads the player state from the file
|
||||
func LoadPlayerState(filePath string) *PlayerState {
|
||||
strData, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := &PlayerState{
|
||||
FilePath: path,
|
||||
FilePath: filePath,
|
||||
}
|
||||
|
||||
err = json.Unmarshal(strData, result)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func CreatePlayerState(heroName string, hero d2enum.Hero, classStats *d2datadict.CharStatsRecord, hardcore bool) *PlayerState {
|
||||
// CreatePlayerState creates a PlayerState instance and returns a pointer to it
|
||||
func CreatePlayerState(heroName string, hero d2enum.Hero, classStats *d2datadict.CharStatsRecord) *PlayerState {
|
||||
result := &PlayerState{
|
||||
HeroName: heroName,
|
||||
HeroType: hero,
|
||||
Act: 1,
|
||||
Stats: d2hero.CreateHeroStatsState(hero, classStats),
|
||||
Stats: d2hero.CreateHeroStatsState(hero, classStats),
|
||||
Equipment: d2inventory.HeroObjects[hero],
|
||||
FilePath: "",
|
||||
}
|
||||
|
||||
result.Save()
|
||||
if err := result.Save(); err != nil {
|
||||
fmt.Printf("failed to save game state!, err: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@ -105,6 +122,7 @@ func getGameBaseSavePath() (string, error) {
|
||||
func getFirstFreeFileName() string {
|
||||
i := 0
|
||||
basePath, _ := getGameBaseSavePath()
|
||||
|
||||
for {
|
||||
filePath := path.Join(basePath, strconv.Itoa(i)+".od2")
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
@ -114,13 +132,19 @@ func getFirstFreeFileName() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (v *PlayerState) Save() {
|
||||
// Save saves the player state to a file
|
||||
func (v *PlayerState) Save() error {
|
||||
if v.FilePath == "" {
|
||||
v.FilePath = getFirstFreeFileName()
|
||||
}
|
||||
if err := os.MkdirAll(path.Dir(v.FilePath), 0755); err != nil {
|
||||
log.Panic(err.Error())
|
||||
return err
|
||||
}
|
||||
fileJson, _ := json.MarshalIndent(v, "", " ")
|
||||
ioutil.WriteFile(v.FilePath, fileJson, 0644)
|
||||
|
||||
fileJSON, _ := json.MarshalIndent(v, "", " ")
|
||||
if err := ioutil.WriteFile(v.FilePath, fileJSON, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user