Lint error cleanup1 (#779)

* fixed lint error in d2app/app.go

* go fmt entire project

* adding doc.go for d2records

* fixed lint issues in d2core/d2map

* fixed lint error in d2interface/palette.go

* fixed lint error in  d2core/d2hero/hero_state_factory.go

* adding dov.go to d2common/d2geom

* fixing lint errors in d2common/d2loader

* adding doc.go to d2common/d2cache

* adding doc files for d2datautils, d2util, d2path

* adding package doc strings for mapgen, in-geam help screen, and tcp client connection

* removed all cuddling lint errors

* changed stamina equality check to '<=' instead of '<'
This commit is contained in:
gravestench 2020-10-22 06:12:06 +01:00 committed by GitHub
parent 30b6f0cb4e
commit 783993470e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 175 additions and 37 deletions

View File

@ -636,8 +636,8 @@ func (a *App) ToCharacterSelect(connType d2clientconnectiontype.ClientConnection
func (a *App) ToMapEngineTest(region, level int) { func (a *App) ToMapEngineTest(region, level int) {
met, err := d2gamescreen.CreateMapEngineTest(region, level, a.asset, a.terminal, a.renderer, a.inputManager, a.audio, a.screen) met, err := d2gamescreen.CreateMapEngineTest(region, level, a.asset, a.terminal, a.renderer, a.inputManager, a.audio, a.screen)
if err != nil { if err != nil {
return
log.Print(err) log.Print(err)
return
} }
a.screen.SetNextScreen(met) a.screen.SetNextScreen(met)

2
d2common/d2cache/doc.go Normal file
View File

@ -0,0 +1,2 @@
// Package d2cache provides a generic caching implementation
package d2cache

View File

@ -0,0 +1,3 @@
// Package d2datautils is a utility package that provides helper functions/classes
// for parsing the original diablo2 files. (eg. parsers for binary files that aren't byte-aligned)
package d2datautils

View File

@ -216,6 +216,7 @@ func (v *MPQ) loadBlockTable() {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
blockData[i] = binary.LittleEndian.Uint32(hash) blockData[i] = binary.LittleEndian.Uint32(hash)
} }

View File

@ -166,10 +166,12 @@ func (v *Stream) bufferData() {
func (v *Stream) loadSingleUnit() { func (v *Stream) loadSingleUnit() {
fileData := make([]byte, v.BlockSize) fileData := make([]byte, v.BlockSize)
_, err := v.MPQData.file.Seek(int64(v.MPQData.data.HeaderSize), 0) _, err := v.MPQData.file.Seek(int64(v.MPQData.data.HeaderSize), 0)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
_, err = v.MPQData.file.Read(fileData) _, err = v.MPQData.file.Read(fileData)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -204,6 +206,7 @@ func (v *Stream) loadBlock(blockIndex, expectedLength uint32) []byte {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
_, err = v.MPQData.file.Read(data) _, err = v.MPQData.file.Read(data)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -294,14 +297,13 @@ func deflate(data []byte) []byte {
} }
buffer := new(bytes.Buffer) buffer := new(bytes.Buffer)
_, err = buffer.ReadFrom(r)
_, err = buffer.ReadFrom(r)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
err = r.Close() err = r.Close()
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
} }
@ -318,14 +320,13 @@ func pkDecompress(data []byte) []byte {
} }
buffer := new(bytes.Buffer) buffer := new(bytes.Buffer)
_, err = buffer.ReadFrom(r)
_, err = buffer.ReadFrom(r)
if err != nil { if err != nil {
panic(err) panic(err)
} }
err = r.Close() err = r.Close()
if err != nil { if err != nil {
panic(err) panic(err)
} }

2
d2common/d2geom/doc.go Normal file
View File

@ -0,0 +1,2 @@
// Package d2geom is a utility package for anything related to geometry
package d2geom

View File

@ -17,6 +17,6 @@ type Color interface {
// Palette is a color palette // Palette is a color palette
type Palette interface { type Palette interface {
NumColors() int NumColors() int
GetColors() [256]Color GetColors() [numColors]Color
GetColor(idx int) (Color, error) GetColor(idx int) (Color, error)
} }

View File

@ -2,6 +2,7 @@ package asset
import ( import (
"fmt" "fmt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2loader/asset/types" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2loader/asset/types"
) )

View File

@ -81,6 +81,7 @@ func TestLoader_AddSource(t *testing.T) {
} }
} }
// nolint:gocyclo // this is just a test, not a big deal if we ignore linter here
func TestLoader_Load(t *testing.T) { func TestLoader_Load(t *testing.T) {
loader := NewLoader(nil) loader := NewLoader(nil)
@ -89,21 +90,25 @@ func TestLoader_Load(t *testing.T) {
t.Fail() t.Fail()
log.Print(err) log.Print(err)
} }
_, err = loader.AddSource(sourcePathD) _, err = loader.AddSource(sourcePathD)
if err != nil { if err != nil {
t.Fail() t.Fail()
log.Print(err) log.Print(err)
} }
_, err = loader.AddSource(sourcePathA) _, err = loader.AddSource(sourcePathA)
if err != nil { if err != nil {
t.Fail() t.Fail()
log.Print(err) log.Print(err)
} }
_, err = loader.AddSource(sourcePathC) _, err = loader.AddSource(sourcePathC)
if err != nil { if err != nil {
t.Fail() t.Fail()
log.Print(err) log.Print(err)
} }
entryCommon, errCommon := loader.Load(commonFile) // common file exists in all three Sources entryCommon, errCommon := loader.Load(commonFile) // common file exists in all three Sources
entryA, errA := loader.Load(exclusiveA) // each source has a file exclusive to itself entryA, errA := loader.Load(exclusiveA) // each source has a file exclusive to itself

2
d2common/d2path/doc.go Normal file
View File

@ -0,0 +1,2 @@
// Package d2path is a utility package for functionality related to map entity pathing
package d2path

View File

@ -92,9 +92,11 @@ func (p *GlyphPrinter) drawDebugText(target *ebiten.Image, str string, ox, oy in
op.CompositeMode = ebiten.CompositeModeLighter op.CompositeMode = ebiten.CompositeModeLighter
err := target.DrawImage(s, op) err := target.DrawImage(s, op)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
x += cw x += cw
} }
} }

3
d2common/d2util/doc.go Normal file
View File

@ -0,0 +1,3 @@
// Package d2util is a utility package for general-purpose functions used frequently throughout the
// codebase.
package d2util

View File

@ -20,6 +20,7 @@ func ImgIndexToRGBA(indexData []byte, palette d2interface.Palette) []byte {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
colorData[i*bytesPerPixel] = c.R() colorData[i*bytesPerPixel] = c.R()
colorData[i*bytesPerPixel+1] = c.G() colorData[i*bytesPerPixel+1] = c.G()
colorData[i*bytesPerPixel+2] = c.B() colorData[i*bytesPerPixel+2] = c.B()

View File

@ -238,6 +238,7 @@ func (a *Animation) GetCurrentFrameSize() (width, height int) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
return width, height return width, height
} }

View File

@ -28,16 +28,19 @@ type Button struct {
func (b *Button) onMouseButtonDown(_ d2interface.MouseEvent) bool { func (b *Button) onMouseButtonDown(_ d2interface.MouseEvent) bool {
b.state = buttonStatePressed b.state = buttonStatePressed
return false return false
} }
func (b *Button) onMouseButtonUp(_ d2interface.MouseEvent) bool { func (b *Button) onMouseButtonUp(_ d2interface.MouseEvent) bool {
b.state = buttonStateDefault b.state = buttonStateDefault
return false return false
} }
func (b *Button) onMouseLeave(_ d2interface.MouseMoveEvent) bool { func (b *Button) onMouseLeave(_ d2interface.MouseMoveEvent) bool {
b.state = buttonStateDefault b.state = buttonStateDefault
return false return false
} }

View File

@ -29,6 +29,7 @@ func createLabel(renderer d2interface.Renderer, text string, font *d2asset.Font)
log.Print(err) log.Print(err)
return nil return nil
} }
label.SetVisible(true) label.SetVisible(true)
return label return label

View File

@ -54,6 +54,7 @@ func (f *HeroStateFactory) CreateHeroState(
defaultStats := f.asset.Records.Character.Stats[hero] defaultStats := f.asset.Records.Character.Stats[hero]
skillState, err := f.CreateHeroSkillsState(defaultStats) skillState, err := f.CreateHeroSkillsState(defaultStats)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -109,7 +110,7 @@ func (f *HeroStateFactory) CreateHeroSkillsState(classStats *d2records.CharStats
for idx := range classStats.BaseSkill { for idx := range classStats.BaseSkill {
skillName := &classStats.BaseSkill[idx] skillName := &classStats.BaseSkill[idx]
if len(*skillName) == 0 { if *skillName == "" {
continue continue
} }

View File

@ -149,6 +149,7 @@ func (f *ItemFactory) NewItem(codes ...string) (*Item, error) {
} }
item.factory = f item.factory = f
return item.init(), nil return item.init(), nil
} }

View File

@ -32,7 +32,7 @@ type MapEngine struct {
startSubTileY int // Starting Y position startSubTileY int // Starting Y position
dt1Files []string // List of DS1 strings dt1Files []string // List of DS1 strings
// TODO: remove this flag and show loading screen until the initial server packets are handled and the map is generated (only for remote client) // TODO: remove this flag and show loading screen until the initial server packets are handled and the map is generated (only for remote client)
IsLoading bool // (temp) Whether we have processed the GenerateMapPacket(only for remote client) IsLoading bool // (temp) Whether we have processed the GenerateMapPacket(only for remote client)
} }
// CreateMapEngine creates a new instance of the map engine and returns a pointer to it. // CreateMapEngine creates a new instance of the map engine and returns a pointer to it.
@ -45,7 +45,7 @@ func CreateMapEngine(asset *d2asset.AssetManager) *MapEngine {
MapEntityFactory: entity, MapEntityFactory: entity,
StampFactory: stamp, StampFactory: stamp,
// This will be set to true when we are using a remote client connection, and then set to false after we process the GenerateMapPacket // This will be set to true when we are using a remote client connection, and then set to false after we process the GenerateMapPacket
IsLoading: false, IsLoading: false,
} }
return engine return engine
@ -93,6 +93,7 @@ func (m *MapEngine) addDT1(fileName string) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
m.dt1TileData = append(m.dt1TileData, dt1.Tiles...) m.dt1TileData = append(m.dt1TileData, dt1.Tiles...)
m.dt1Files = append(m.dt1Files, fileName) m.dt1Files = append(m.dt1Files, fileName)
} }

View File

@ -192,9 +192,11 @@ func (f *MapEntityFactory) NewNPC(x, y int, monstat *d2records.MonStatsRecord, d
composite, err := f.asset.LoadComposite(d2enum.ObjectTypeCharacter, monstat.AnimationDirectoryToken, composite, err := f.asset.LoadComposite(d2enum.ObjectTypeCharacter, monstat.AnimationDirectoryToken,
d2resource.PaletteUnits) d2resource.PaletteUnits)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result.composite = composite result.composite = composite
if err := composite.SetMode(d2enum.MonsterAnimationModeNeutral, if err := composite.SetMode(d2enum.MonsterAnimationModeNeutral,

View File

@ -2,6 +2,7 @@ package d2mapentity
import ( import (
"fmt" "fmt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector"
@ -109,7 +110,7 @@ func (p *Player) Advance(tickTime float64) {
// Drain and regenerate Stamina // Drain and regenerate Stamina
if p.IsRunning() && !p.atTarget() && !p.IsInTown() { if p.IsRunning() && !p.atTarget() && !p.IsInTown() {
p.Stats.Stamina -= float64(p.composite.AssetManager.Records.Character.Stats[p.Class].StaminaRunDrain) * tickTime / 5 p.Stats.Stamina -= float64(p.composite.AssetManager.Records.Character.Stats[p.Class].StaminaRunDrain) * tickTime / 5
if p.Stats.Stamina < 0 { if p.Stats.Stamina <= 0 {
p.SetSpeed(baseWalkSpeed) p.SetSpeed(baseWalkSpeed)
p.Stats.Stamina = 0 p.Stats.Stamina = 0
} }

View File

@ -1,3 +1,4 @@
// Package d2wilderness provides an enumeration of wilderness types
package d2wilderness package d2wilderness
// nolint: golint // these probably don't require individual explanations. // nolint: golint // these probably don't require individual explanations.

View File

@ -130,6 +130,7 @@ func (mr *MapRenderer) Render(target d2interface.Surface) {
if mr.mapEngine.IsLoading { if mr.mapEngine.IsLoading {
return return
} }
mapSize := mr.mapEngine.Size() mapSize := mr.mapEngine.Size()
stxf, styf := mr.viewport.ScreenToWorld(screenMiddleX, -200) stxf, styf := mr.viewport.ScreenToWorld(screenMiddleX, -200)

View File

@ -3,17 +3,17 @@ package d2maprenderer
import ( import (
"log" "log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
) )
func (mr *MapRenderer) generateTileCache() { func (mr *MapRenderer) generateTileCache() {
var err error var err error
mr.palette, err = mr.loadPaletteForAct(d2enum.RegionIdType(mr.mapEngine.LevelType().ID)) mr.palette, err = mr.loadPaletteForAct(d2enum.RegionIdType(mr.mapEngine.LevelType().ID))
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
@ -88,6 +88,7 @@ func (mr *MapRenderer) generateFloorCache(tile *d2ds1.FloorShadowRecord) {
tileYOffset := d2math.AbsInt32(tileYMinimum) tileYOffset := d2math.AbsInt32(tileYMinimum)
tileHeight := d2math.AbsInt32(tileData[i].Height) tileHeight := d2math.AbsInt32(tileData[i].Height)
image, err := mr.renderer.NewSurface(int(tileData[i].Width), int(tileHeight), d2enum.FilterNearest) image, err := mr.renderer.NewSurface(int(tileData[i].Width), int(tileHeight), d2enum.FilterNearest)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
@ -100,6 +101,7 @@ func (mr *MapRenderer) generateFloorCache(tile *d2ds1.FloorShadowRecord) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
mr.setImageCacheRecord(tile.Style, tile.Sequence, 0, tileIndex, image) mr.setImageCacheRecord(tile.Style, tile.Sequence, 0, tileIndex, image)
} }
} }

View File

@ -13,16 +13,20 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
) )
// NewStampFactory creates a MapStamp factory instance
func NewStampFactory(asset *d2asset.AssetManager, entity *d2mapentity.MapEntityFactory) *StampFactory { func NewStampFactory(asset *d2asset.AssetManager, entity *d2mapentity.MapEntityFactory) *StampFactory {
return &StampFactory{asset, entity} return &StampFactory{asset, entity}
} }
// StampFactory is responsible for loading map stamps. A stamp can be thought of like a
// preset map configuration, like the various configurations of Act 1 town.
type StampFactory struct { type StampFactory struct {
asset *d2asset.AssetManager asset *d2asset.AssetManager
entity *d2mapentity.MapEntityFactory entity *d2mapentity.MapEntityFactory
} }
// LoadStamp loads the Stamp data from file. // LoadStamp loads the Stamp data from file, using the given level type, level preset index, and
// level file index.
func (f *StampFactory) LoadStamp(levelType d2enum.RegionIdType, levelPreset, fileIndex int) *Stamp { func (f *StampFactory) LoadStamp(levelType d2enum.RegionIdType, levelPreset, fileIndex int) *Stamp {
stamp := &Stamp{ stamp := &Stamp{
factory: f, factory: f,
@ -33,20 +37,22 @@ func (f *StampFactory) LoadStamp(levelType d2enum.RegionIdType, levelPreset, fil
} }
for _, levelTypeDt1 := range &stamp.levelType.Files { for _, levelTypeDt1 := range &stamp.levelType.Files {
if levelTypeDt1 != "" && levelTypeDt1 != "0" { if levelTypeDt1 == "" || levelTypeDt1 == "0" {
fileData, err := f.asset.LoadFile("/data/global/tiles/" + levelTypeDt1) continue
if err != nil {
panic(err)
}
dt1, err := d2dt1.LoadDT1(fileData)
if err != nil {
log.Print(err)
return nil
}
stamp.tiles = append(stamp.tiles, dt1.Tiles...)
} }
fileData, err := f.asset.LoadFile("/data/global/tiles/" + levelTypeDt1)
if err != nil {
panic(err)
}
dt1, err := d2dt1.LoadDT1(fileData)
if err != nil {
log.Print(err)
return nil
}
stamp.tiles = append(stamp.tiles, dt1.Tiles...)
} }
var levelFilesToPick []string var levelFilesToPick []string

8
d2core/d2records/doc.go Normal file
View File

@ -0,0 +1,8 @@
// d2records provides a RecordManager implementation which is used to parse
// the various txt files from the d2 mpq archives. Each data dictionary (txt file) is
// parsed into slices or maps of structs. There is a struct type defined for each txt file.
//
// The RecordManager is a singleton that loads all of the txt files and export them as
// data members. The RecordManager is meant to be used a a singleton member, exported by the
// AssetManager in d2core/d2asset.
package d2records

View File

@ -14,7 +14,7 @@ func objectDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
for d.Next() { for d.Next() {
record := &ObjectDetailsRecord{ record := &ObjectDetailsRecord{
Index: i, Index: i,
Name: d.String("Name"), Name: d.String("Name"),
Description: d.String("description - not loaded"), Description: d.String("description - not loaded"),
id: d.Number("Id"), id: d.Number("Id"),

View File

@ -277,7 +277,6 @@ func skillDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return nil return nil
} }
func animToEnum(anim string) d2enum.PlayerAnimationMode { func animToEnum(anim string) d2enum.PlayerAnimationMode {
switch anim { switch anim {
case "SC": case "SC":

View File

@ -220,6 +220,7 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
log.Print(err) log.Print(err)
return nil return nil
} }
btn.width += w btn.width += w
} }
@ -251,6 +252,7 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
func (v *Button) renderFrames(btnSprite *Sprite, btnLayout *ButtonLayout, label *Label) { func (v *Button) renderFrames(btnSprite *Sprite, btnLayout *ButtonLayout, label *Label) {
var err error var err error
totalButtonTypes := btnSprite.GetFrameCount() / (btnLayout.XSegments * btnLayout.YSegments) totalButtonTypes := btnSprite.GetFrameCount() / (btnLayout.XSegments * btnLayout.YSegments)
err = btnSprite.RenderSegmented(v.normalSurface, btnLayout.XSegments, btnLayout.YSegments, btnLayout.BaseFrame) err = btnSprite.RenderSegmented(v.normalSurface, btnLayout.XSegments, btnLayout.YSegments, btnLayout.BaseFrame)

View File

@ -26,6 +26,7 @@ type Checkbox struct {
// NewCheckbox creates a new instance of a checkbox // NewCheckbox creates a new instance of a checkbox
func (ui *UIManager) NewCheckbox(checkState bool) *Checkbox { func (ui *UIManager) NewCheckbox(checkState bool) *Checkbox {
var err error var err error
result := &Checkbox{ result := &Checkbox{
checkState: checkState, checkState: checkState,
visible: true, visible: true,
@ -45,6 +46,7 @@ func (ui *UIManager) NewCheckbox(checkState bool) *Checkbox {
log.Print(err) log.Print(err)
return nil return nil
} }
checkboxSprite.SetPosition(0, 0) checkboxSprite.SetPosition(0, 0)
result.Image, err = ui.renderer.NewSurface(result.width, result.height, d2enum.FilterNearest) result.Image, err = ui.renderer.NewSurface(result.width, result.height, d2enum.FilterNearest)
@ -84,6 +86,7 @@ func (v *Checkbox) bindManager(manager *UIManager) {
// Render renders the checkbox // Render renders the checkbox
func (v *Checkbox) Render(target d2interface.Surface) error { func (v *Checkbox) Render(target d2interface.Surface) error {
var err error var err error
target.PushTranslation(v.x, v.y) target.PushTranslation(v.x, v.y)
defer target.Pop() defer target.Pop()

View File

@ -53,6 +53,7 @@ func (ui *UIManager) addWidget(widget Widget) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
ui.widgets = append(ui.widgets, widget) ui.widgets = append(ui.widgets, widget)
widget.bindManager(ui) widget.bindManager(ui)

View File

@ -143,6 +143,7 @@ const (
// OnLoad loads the resources for the Character Select screen // OnLoad loads the resources for the Character Select screen
func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) { func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
var err error var err error
v.audioProvider.PlayBGM(d2resource.BGMTitle) v.audioProvider.PlayBGM(d2resource.BGMTitle)
if err := v.inputManager.BindHandler(v); err != nil { if err := v.inputManager.BindHandler(v); err != nil {
@ -152,10 +153,12 @@ func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
loading.Progress(tenPercent) loading.Progress(tenPercent)
bgX, bgY := 0, 0 bgX, bgY := 0, 0
v.background, err = v.uiManager.NewSprite(d2resource.CharacterSelectionBackground, d2resource.PaletteSky) v.background, err = v.uiManager.NewSprite(d2resource.CharacterSelectionBackground, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.background.SetPosition(bgX, bgY) v.background.SetPosition(bgX, bgY)
v.createButtons(loading) v.createButtons(loading)
@ -178,6 +181,7 @@ func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
selBoxX, selBoxY := 37, 86 selBoxX, selBoxY := 37, 86
v.selectionBox.SetPosition(selBoxX, selBoxY) v.selectionBox.SetPosition(selBoxX, selBoxY)
@ -185,6 +189,7 @@ func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
okCancelX, okCancelY := 270, 175 okCancelX, okCancelY := 270, 175
v.okCancelBox.SetPosition(okCancelX, okCancelY) v.okCancelBox.SetPosition(okCancelX, okCancelY)
@ -196,6 +201,7 @@ func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
offsetX, offsetY := rootLabelOffsetX, rootLabelOffsetY+((i/2)*95) offsetX, offsetY := rootLabelOffsetX, rootLabelOffsetY+((i/2)*95)
if i&1 > 0 { if i&1 > 0 {
offsetX = 385 offsetX = 385
} }
@ -205,10 +211,12 @@ func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
v.characterNameLabel[i].Color[0] = rgbaColor(lightBrown) v.characterNameLabel[i].Color[0] = rgbaColor(lightBrown)
offsetY += labelHeight offsetY += labelHeight
v.characterStatsLabel[i] = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.characterStatsLabel[i] = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits)
v.characterStatsLabel[i].SetPosition(offsetX, offsetY) v.characterStatsLabel[i].SetPosition(offsetX, offsetY)
offsetY += labelHeight offsetY += labelHeight
v.characterExpLabel[i] = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteStatic) v.characterExpLabel[i] = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteStatic)
v.characterExpLabel[i].SetPosition(offsetX, offsetY) v.characterExpLabel[i].SetPosition(offsetX, offsetY)
v.characterExpLabel[i].Color[0] = rgbaColor(lightGreen) v.characterExpLabel[i].Color[0] = rgbaColor(lightGreen)
@ -287,6 +295,7 @@ func (v *CharacterSelect) updateCharacterBoxes() {
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
idx := i + (v.charScrollbar.GetCurrentOffset() * 2) idx := i + (v.charScrollbar.GetCurrentOffset() * 2)
if idx >= len(v.gameStates) { if idx >= len(v.gameStates) {
v.characterNameLabel[i].SetText("") v.characterNameLabel[i].SetText("")
v.characterStatsLabel[i].SetText("") v.characterStatsLabel[i].SetText("")
@ -455,6 +464,7 @@ func (v *CharacterSelect) onDeleteCharacterConfirmClicked() {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.charScrollbar.SetCurrentOffset(0) v.charScrollbar.SetCurrentOffset(0)
v.refreshGameStates() v.refreshGameStates()
v.toggleDeleteCharacterDialog(false) v.toggleDeleteCharacterDialog(false)

View File

@ -90,10 +90,12 @@ func (v *Credits) LoadContributors() []string {
// OnLoad is called to load the resources for the credits screen // OnLoad is called to load the resources for the credits screen
func (v *Credits) OnLoad(loading d2screen.LoadingState) { func (v *Credits) OnLoad(loading d2screen.LoadingState) {
var err error var err error
v.creditsBackground, err = v.uiManager.NewSprite(d2resource.CreditsBackground, d2resource.PaletteSky) v.creditsBackground, err = v.uiManager.NewSprite(d2resource.CreditsBackground, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.creditsBackground.SetPosition(creditsX, creditsY) v.creditsBackground.SetPosition(creditsX, creditsY)
loading.Progress(twentyPercent) loading.Progress(twentyPercent)

View File

@ -208,6 +208,7 @@ func (v *Game) Render(screen d2interface.Surface) error {
// When help overlay is open, put transparent black screen. Magic noumber is hex for RGBA. // When help overlay is open, put transparent black screen. Magic noumber is hex for RGBA.
screen.DrawRect(800, 600, d2util.Color(0x0000007f)) screen.DrawRect(800, 600, d2util.Color(0x0000007f))
} }
if err := v.gameControls.Render(screen); err != nil { if err := v.gameControls.Render(screen); err != nil {
return err return err
} }

View File

@ -183,28 +183,33 @@ func (v *MainMenu) OnLoad(loading d2screen.LoadingState) {
func (v *MainMenu) loadBackgroundSprites() { func (v *MainMenu) loadBackgroundSprites() {
var err error var err error
v.background, err = v.uiManager.NewSprite(d2resource.GameSelectScreen, d2resource.PaletteSky) v.background, err = v.uiManager.NewSprite(d2resource.GameSelectScreen, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.background.SetPosition(backgroundX, backgroundY) v.background.SetPosition(backgroundX, backgroundY)
v.trademarkBackground, err = v.uiManager.NewSprite(d2resource.TrademarkScreen, d2resource.PaletteSky) v.trademarkBackground, err = v.uiManager.NewSprite(d2resource.TrademarkScreen, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.trademarkBackground.SetPosition(backgroundX, backgroundY) v.trademarkBackground.SetPosition(backgroundX, backgroundY)
v.tcpIPBackground, err = v.uiManager.NewSprite(d2resource.TCPIPBackground, d2resource.PaletteSky) v.tcpIPBackground, err = v.uiManager.NewSprite(d2resource.TCPIPBackground, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.tcpIPBackground.SetPosition(backgroundX, backgroundY) v.tcpIPBackground.SetPosition(backgroundX, backgroundY)
v.serverIPBackground, err = v.uiManager.NewSprite(d2resource.PopUpOkCancel, d2resource.PaletteFechar) v.serverIPBackground, err = v.uiManager.NewSprite(d2resource.PopUpOkCancel, d2resource.PaletteFechar)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.serverIPBackground.SetPosition(serverIPbackgroundX, serverIPbackgroundY) v.serverIPBackground.SetPosition(serverIPbackgroundX, serverIPbackgroundY)
} }
@ -248,18 +253,22 @@ func (v *MainMenu) createLabels(loading d2screen.LoadingState) {
v.tcpJoinGameLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits) v.tcpJoinGameLabel = v.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteUnits)
v.tcpJoinGameLabel.Alignment = d2gui.HorizontalAlignCenter v.tcpJoinGameLabel.Alignment = d2gui.HorizontalAlignCenter
v.tcpJoinGameLabel.SetText("Enter Host IP Address\nto Join Game") v.tcpJoinGameLabel.SetText("Enter Host IP Address\nto Join Game")
v.tcpJoinGameLabel.Color[0] = rgbaColor(gold) v.tcpJoinGameLabel.Color[0] = rgbaColor(gold)
v.tcpJoinGameLabel.SetPosition(joinGameX, joinGameY) v.tcpJoinGameLabel.SetPosition(joinGameX, joinGameY)
} }
func (v *MainMenu) createLogos(loading d2screen.LoadingState) { func (v *MainMenu) createLogos(loading d2screen.LoadingState) {
var err error var err error
v.diabloLogoLeft, err = v.uiManager.NewSprite(d2resource.Diablo2LogoFireLeft, d2resource.PaletteUnits) v.diabloLogoLeft, err = v.uiManager.NewSprite(d2resource.Diablo2LogoFireLeft, d2resource.PaletteUnits)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.diabloLogoLeft.SetEffect(d2enum.DrawEffectModulate) v.diabloLogoLeft.SetEffect(d2enum.DrawEffectModulate)
v.diabloLogoLeft.PlayForward() v.diabloLogoLeft.PlayForward()
v.diabloLogoLeft.SetPosition(diabloLogoX, diabloLogoY) v.diabloLogoLeft.SetPosition(diabloLogoX, diabloLogoY)
@ -269,6 +278,7 @@ func (v *MainMenu) createLogos(loading d2screen.LoadingState) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.diabloLogoRight.SetEffect(d2enum.DrawEffectModulate) v.diabloLogoRight.SetEffect(d2enum.DrawEffectModulate)
v.diabloLogoRight.PlayForward() v.diabloLogoRight.PlayForward()
v.diabloLogoRight.SetPosition(diabloLogoX, diabloLogoY) v.diabloLogoRight.SetPosition(diabloLogoX, diabloLogoY)
@ -277,12 +287,14 @@ func (v *MainMenu) createLogos(loading d2screen.LoadingState) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.diabloLogoLeftBack.SetPosition(diabloLogoX, diabloLogoY) v.diabloLogoLeftBack.SetPosition(diabloLogoX, diabloLogoY)
v.diabloLogoRightBack, err = v.uiManager.NewSprite(d2resource.Diablo2LogoBlackRight, d2resource.PaletteUnits) v.diabloLogoRightBack, err = v.uiManager.NewSprite(d2resource.Diablo2LogoBlackRight, d2resource.PaletteUnits)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
v.diabloLogoRightBack.SetPosition(diabloLogoX, diabloLogoY) v.diabloLogoRightBack.SetPosition(diabloLogoX, diabloLogoY)
} }

View File

@ -229,6 +229,7 @@ func (m *EscapeMenu) wrapLayout(fn func(*layout)) *layout {
left := center.AddLayout(d2gui.PositionTypeVertical) left := center.AddLayout(d2gui.PositionTypeVertical)
left.SetSize(sidePanelsSize, pentSize) left.SetSize(sidePanelsSize, pentSize)
leftPent, err := left.AddAnimatedSprite(d2resource.PentSpin, d2resource.PaletteUnits, d2gui.DirectionBackward) leftPent, err := left.AddAnimatedSprite(d2resource.PentSpin, d2resource.PaletteUnits, d2gui.DirectionBackward)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
return nil return nil
@ -248,6 +249,7 @@ func (m *EscapeMenu) wrapLayout(fn func(*layout)) *layout {
right.AddSpacerStatic(sidePanelsSize-pentSize, 0) right.AddSpacerStatic(sidePanelsSize-pentSize, 0)
right.SetSize(sidePanelsSize, pentSize) right.SetSize(sidePanelsSize, pentSize)
rightPent, err := right.AddAnimatedSprite(d2resource.PentSpin, d2resource.PaletteUnits, d2gui.DirectionForward) rightPent, err := right.AddAnimatedSprite(d2resource.PentSpin, d2resource.PaletteUnits, d2gui.DirectionForward)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
return nil return nil
@ -290,12 +292,14 @@ func (m *EscapeMenu) addBigSelectionLabel(l *layout, text string, targetLayout l
label.SetMouseEnterHandler(func(_ d2interface.MouseMoveEvent) { label.SetMouseEnterHandler(func(_ d2interface.MouseMoveEvent) {
m.onHoverElement(elID) m.onHoverElement(elID)
}) })
l.AddSpacerStatic(spacerWidth, labelGutter) l.AddSpacerStatic(spacerWidth, labelGutter)
l.actionableElements = append(l.actionableElements, label) l.actionableElements = append(l.actionableElements, label)
} }
func (m *EscapeMenu) addPreviousMenuLabel(l *layout) { func (m *EscapeMenu) addPreviousMenuLabel(l *layout) {
l.AddSpacerStatic(spacerWidth, labelGutter) l.AddSpacerStatic(spacerWidth, labelGutter)
guiLabel, err := l.AddLabel("PREVIOUS MENU", d2gui.FontStyle30Units) guiLabel, err := l.AddLabel("PREVIOUS MENU", d2gui.FontStyle30Units)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -330,7 +334,9 @@ func (m *EscapeMenu) addEnumLabel(l *layout, optID optionID, text string, values
layout.SetMouseEnterHandler(func(_ d2interface.MouseMoveEvent) { layout.SetMouseEnterHandler(func(_ d2interface.MouseMoveEvent) {
m.onHoverElement(elID) m.onHoverElement(elID)
}) })
layout.AddSpacerDynamic() layout.AddSpacerDynamic()
guiLabel, err := layout.AddLabel(values[0], d2gui.FontStyle30Units) guiLabel, err := layout.AddLabel(values[0], d2gui.FontStyle30Units)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -350,11 +356,13 @@ func (m *EscapeMenu) addEnumLabel(l *layout, optID optionID, text string, values
label.Trigger() label.Trigger()
}) })
l.AddSpacerStatic(spacerWidth, labelGutter) l.AddSpacerStatic(spacerWidth, labelGutter)
l.actionableElements = append(l.actionableElements, label) l.actionableElements = append(l.actionableElements, label)
} }
func (m *EscapeMenu) OnLoad() { func (m *EscapeMenu) OnLoad() {
var err error var err error
m.selectSound, err = m.audioProvider.LoadSound(d2resource.SFXCursorSelect, false, false) m.selectSound, err = m.audioProvider.LoadSound(d2resource.SFXCursorSelect, false, false)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -415,6 +423,7 @@ func (m *EscapeMenu) onHoverElement(id int) {
x, _ := m.leftPent.GetPosition() x, _ := m.leftPent.GetPosition()
m.leftPent.SetPosition(x, y+spacerWidth) m.leftPent.SetPosition(x, y+spacerWidth)
x, _ = m.rightPent.GetPosition() x, _ = m.rightPent.GetPosition()
m.rightPent.SetPosition(x, y+spacerWidth) m.rightPent.SetPosition(x, y+spacerWidth)
} }
@ -428,6 +437,7 @@ func (m *EscapeMenu) setLayout(id layoutID) {
m.rightPent = m.layouts[id].rightPent m.rightPent = m.layouts[id].rightPent
m.currentLayout = id m.currentLayout = id
m.layouts[id].currentEl = len(m.layouts[id].actionableElements) - 1 // default to Previous Menu m.layouts[id].currentEl = len(m.layouts[id].actionableElements) - 1 // default to Previous Menu
m.guiManager.SetLayout(m.layouts[id].Layout) m.guiManager.SetLayout(m.layouts[id].Layout)
// when first rendering a layout, widgets don't have offsets so we hide pentagrams for a frame // when first rendering a layout, widgets don't have offsets so we hide pentagrams for a frame
@ -435,6 +445,7 @@ func (m *EscapeMenu) setLayout(id layoutID) {
m.layouts[id].rendered = true m.layouts[id].rendered = true
m.leftPent.SetVisible(false) m.leftPent.SetVisible(false)
m.rightPent.SetVisible(false) m.rightPent.SetVisible(false)
go func() { go func() {
time.Sleep(16 * time.Millisecond) time.Sleep(16 * time.Millisecond)
m.onHoverElement(m.layouts[id].currentEl) m.onHoverElement(m.layouts[id].currentEl)
@ -454,6 +465,7 @@ func (m *EscapeMenu) onUpKey() {
if m.layouts[m.currentLayout].currentEl == 0 { if m.layouts[m.currentLayout].currentEl == 0 {
return return
} }
m.layouts[m.currentLayout].currentEl-- m.layouts[m.currentLayout].currentEl--
m.onHoverElement(m.layouts[m.currentLayout].currentEl) m.onHoverElement(m.layouts[m.currentLayout].currentEl)
} }
@ -466,6 +478,7 @@ func (m *EscapeMenu) onDownKey() {
if m.layouts[m.currentLayout].currentEl == len(m.layouts[m.currentLayout].actionableElements)-1 { if m.layouts[m.currentLayout].currentEl == len(m.layouts[m.currentLayout].actionableElements)-1 {
return return
} }
m.layouts[m.currentLayout].currentEl++ m.layouts[m.currentLayout].currentEl++
m.onHoverElement(m.layouts[m.currentLayout].currentEl) m.onHoverElement(m.layouts[m.currentLayout].currentEl)
} }

View File

@ -334,23 +334,28 @@ func (g *GameControls) OnKeyUp(event d2interface.KeyEvent) bool {
return false return false
} }
// When escape is pressed:
// 1. If there was some overlay or panel open, close it
// 2. Otherwise, if the Escape Menu was open, let the Escape Menu handle it
// 3. If nothing was open, open the Escape Menu
func (g *GameControls) onEscKey() { func (g *GameControls) onEscKey() {
// When escape is pressed:
// 1. If there was some overlay or panel open, close it
// 2. Otherwise, if the Escape Menu was open, let the Escape Menu handle it
// 3. If nothing was open, open the Escape Menu
escHandled := false escHandled := false
if g.inventory.IsOpen() { if g.inventory.IsOpen() {
g.inventory.Close() g.inventory.Close()
escHandled = true escHandled = true
} }
if g.heroStatsPanel.IsOpen() { if g.heroStatsPanel.IsOpen() {
g.heroStatsPanel.Close() g.heroStatsPanel.Close()
escHandled = true escHandled = true
} }
if g.HelpOverlay.IsOpen() { if g.HelpOverlay.IsOpen() {
g.HelpOverlay.Toggle() g.HelpOverlay.Toggle()
escHandled = true escHandled = true
} }
@ -476,6 +481,7 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
// Load the resources required for the GameControls // Load the resources required for the GameControls
func (g *GameControls) Load() { func (g *GameControls) Load() {
var err error var err error
g.globeSprite, err = g.ui.NewSprite(d2resource.GameGlobeOverlap, d2resource.PaletteSky) g.globeSprite, err = g.ui.NewSprite(d2resource.GameGlobeOverlap, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -495,6 +501,7 @@ func (g *GameControls) Load() {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
err = g.menuButton.SetCurrentFrame(2) err = g.menuButton.SetCurrentFrame(2)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -1010,6 +1017,7 @@ func (g *GameControls) Render(target d2interface.Surface) error {
g.nameLabel.SetPosition(255, 535) g.nameLabel.SetPosition(255, 535)
g.nameLabel.Render(target) g.nameLabel.Render(target)
} }
return nil return nil
} }

View File

@ -1,3 +1,4 @@
// Package help contains the in-game diablo2 help panel
package help package help
import ( import (
@ -58,6 +59,7 @@ func NewHelpOverlay(
func (h *Overlay) Toggle() { func (h *Overlay) Toggle() {
fmt.Print("Help overlay toggled\n") fmt.Print("Help overlay toggled\n")
if h.isOpen { if h.isOpen {
h.close() h.close()
} else { } else {
@ -95,6 +97,7 @@ func (h *Overlay) IsInRect(px, py int) bool {
if px >= x && px <= x+ww && py >= y && py <= y+hh { if px >= x && px <= x+ww && py >= y && py <= y+hh {
return true return true
} }
return false return false
} }
@ -106,6 +109,7 @@ func (h *Overlay) Load() {
prevX = 0 prevX = 0
prevY = 0 prevY = 0
) )
for frameIndex := 0; frameIndex < 7; frameIndex++ { for frameIndex := 0; frameIndex < 7; frameIndex++ {
f, err := h.uiManager.NewSprite(d2resource.HelpBorder, d2resource.PaletteSky) f, err := h.uiManager.NewSprite(d2resource.HelpBorder, d2resource.PaletteSky)
if err != nil { if err != nil {
@ -176,6 +180,7 @@ func (h *Overlay) Load() {
// Bullets // Bullets
yOffset := 59 yOffset := 59
h.createBullet(callout{ h.createBullet(callout{
LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp2"), "Ctrl"), // TODO "Ctrl" should be hotkey // "Hold Down <%s> to Run" LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp2"), "Ctrl"), // TODO "Ctrl" should be hotkey // "Hold Down <%s> to Run"
LabelX: 100, LabelX: 100,
@ -185,6 +190,7 @@ func (h *Overlay) Load() {
}) })
yOffset += 20 yOffset += 20
h.createBullet(callout{ h.createBullet(callout{
LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp3"), "Alt"), // TODO "Alt" should be hotkey // "Hold down <%s> to highlight items on the ground" LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp3"), "Alt"), // TODO "Alt" should be hotkey // "Hold down <%s> to highlight items on the ground"
LabelX: 100, LabelX: 100,
@ -194,6 +200,7 @@ func (h *Overlay) Load() {
}) })
yOffset += 20 yOffset += 20
h.createBullet(callout{ h.createBullet(callout{
LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp4"), "Shift"), // TODO "Shift" should be hotkey // "Hold down <%s> to attack while standing still" LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp4"), "Shift"), // TODO "Shift" should be hotkey // "Hold down <%s> to attack while standing still"
LabelX: 100, LabelX: 100,
@ -203,6 +210,7 @@ func (h *Overlay) Load() {
}) })
yOffset += 20 yOffset += 20
h.createBullet(callout{ h.createBullet(callout{
LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp5"), "Tab"), // TODO "Tab" should be hotkey // "Hit <%s> to toggle the automap on and off" LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp5"), "Tab"), // TODO "Tab" should be hotkey // "Hit <%s> to toggle the automap on and off"
LabelX: 100, LabelX: 100,
@ -212,6 +220,7 @@ func (h *Overlay) Load() {
}) })
yOffset += 20 yOffset += 20
h.createBullet(callout{ h.createBullet(callout{
LabelText: d2tbl.TranslateString("StrHelp6"), // "Hit <Esc> to bring up the Game Menu" LabelText: d2tbl.TranslateString("StrHelp6"), // "Hit <Esc> to bring up the Game Menu"
LabelX: 100, LabelX: 100,
@ -221,6 +230,7 @@ func (h *Overlay) Load() {
}) })
yOffset += 20 yOffset += 20
h.createBullet(callout{ h.createBullet(callout{
LabelText: d2tbl.TranslateString("StrHelp7"), // "Hit <Enter> to go into chat mode" LabelText: d2tbl.TranslateString("StrHelp7"), // "Hit <Enter> to go into chat mode"
LabelX: 100, LabelX: 100,
@ -230,6 +240,7 @@ func (h *Overlay) Load() {
}) })
yOffset += 20 yOffset += 20
h.createBullet(callout{ h.createBullet(callout{
LabelText: d2tbl.TranslateString("StrHelp8"), // "Hit F1-F8 to set your Left or Right Mouse Buttton Skills." LabelText: d2tbl.TranslateString("StrHelp8"), // "Hit F1-F8 to set your Left or Right Mouse Buttton Skills."
LabelX: 100, LabelX: 100,
@ -239,6 +250,7 @@ func (h *Overlay) Load() {
}) })
yOffset += 20 yOffset += 20
h.createBullet(callout{ h.createBullet(callout{
LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp8a"), "H"), // TODO "H" should be hotkey LabelText: fmt.Sprintf(d2tbl.TranslateString("StrHelp8a"), "H"), // TODO "H" should be hotkey
LabelX: 100, LabelX: 100,
@ -391,7 +403,6 @@ func (h *Overlay) Load() {
DotX: 530, DotX: 530,
DotY: 568, DotY: 568,
}) })
} }
type line struct { type line struct {
@ -426,6 +437,7 @@ func (h *Overlay) createBullet(c callout) {
if err != nil { if err != nil {
log.Print(err) log.Print(err)
} }
newDot.SetPosition(c.DotX, c.DotY+14) newDot.SetPosition(c.DotX, c.DotY+14)
h.frames = append(h.frames, newDot) h.frames = append(h.frames, newDot)
} }
@ -456,6 +468,7 @@ func (h *Overlay) createCallout(c callout) {
MoveY: c.DotY - c.LabelY - hh - 5, MoveY: c.DotY - c.LabelY - hh - 5,
Color: color.White, Color: color.White,
} }
h.lines = append(h.lines, l) h.lines = append(h.lines, l)
newDot, err := h.uiManager.NewSprite(d2resource.HelpWhiteBullet, d2resource.PaletteSky) newDot, err := h.uiManager.NewSprite(d2resource.HelpWhiteBullet, d2resource.PaletteSky)

View File

@ -80,6 +80,7 @@ func NewHeroStatsPanel(asset *d2asset.AssetManager, ui *d2ui.UIManager, heroName
// Load the data for the hero status panel // Load the data for the hero status panel
func (s *HeroStatsPanel) Load() { func (s *HeroStatsPanel) Load() {
var err error var err error
s.frame, err = s.uiManager.NewSprite(d2resource.Frame, d2resource.PaletteSky) s.frame, err = s.uiManager.NewSprite(d2resource.Frame, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -123,6 +123,7 @@ func (g *ItemGrid) loadItem(item InventoryItem) {
// TODO: Put the pattern into D2Shared // TODO: Put the pattern into D2Shared
imgPath := fmt.Sprintf("/data/global/items/inv%s.dc6", item.GetItemCode()) imgPath := fmt.Sprintf("/data/global/items/inv%s.dc6", item.GetItemCode())
itemSprite, err := g.uiManager.NewSprite(imgPath, d2resource.PaletteSky) itemSprite, err := g.uiManager.NewSprite(imgPath, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Printf("Failed to load sprite, error: " + err.Error()) log.Printf("Failed to load sprite, error: " + err.Error())
@ -223,6 +224,7 @@ func (g *ItemGrid) renderItem(item InventoryItem, target d2interface.Surface, x,
if itemSprite != nil { if itemSprite != nil {
itemSprite.SetPosition(x, y) itemSprite.SetPosition(x, y)
itemSprite.GetCurrentFrameSize() itemSprite.GetCurrentFrameSize()
err := itemSprite.Render(target) err := itemSprite.Render(target)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -198,6 +198,7 @@ func (r *RemoteClientConnection) decodeToPacket(t d2netpackettype.NetPacketType,
if err = json.Unmarshal([]byte(data), &p); err != nil { if err = json.Unmarshal([]byte(data), &p); err != nil {
break break
} }
np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)} np = d2netpacket.NetPacket{PacketType: t, PacketData: d2netpacket.MarshalPacket(p)}
case d2netpackettype.CastSkill: case d2netpackettype.CastSkill:

View File

@ -279,6 +279,7 @@ func (g *GameClient) handleCastSkillPacket(packet d2netpacket.NetPacket) error {
player.SetDirection(direction) player.SetDirection(direction)
skillRecord := g.asset.Records.Skill.Details[playerCast.SkillID] skillRecord := g.asset.Records.Skill.Details[playerCast.SkillID]
missileEntity, err := g.createMissileEntity(skillRecord, player, castX, castY) missileEntity, err := g.createMissileEntity(skillRecord, player, castX, castY)
if err != nil { if err != nil {
return err return err

View File

@ -38,6 +38,7 @@ func CreateAddPlayerPacket(id, name string, x, y int, heroType d2enum.Hero,
Stats: stats, Stats: stats,
Skills: skills, Skills: skills,
} }
b, err := json.Marshal(addPlayerPacket) b, err := json.Marshal(addPlayerPacket)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -21,6 +21,7 @@ func CreateGenerateMapPacket(regionType d2enum.RegionIdType) NetPacket {
generateMapPacket := GenerateMapPacket{ generateMapPacket := GenerateMapPacket{
RegionType: regionType, RegionType: regionType,
} }
b, err := json.Marshal(generateMapPacket) b, err := json.Marshal(generateMapPacket)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -22,6 +22,7 @@ func CreateSpawnItemPacket(x, y int, codes ...string) NetPacket {
Y: y, Y: y,
Codes: codes, Codes: codes,
} }
b, err := json.Marshal(spawnItemPacket) b, err := json.Marshal(spawnItemPacket)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -28,6 +28,7 @@ func CreateMovePlayerPacket(playerID string, startX, startY, destX, destY float6
DestX: destX, DestX: destX,
DestY: destY, DestY: destY,
} }
b, err := json.Marshal(movePlayerPacket) b, err := json.Marshal(movePlayerPacket)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -20,6 +20,7 @@ func CreatePingPacket() NetPacket {
ping := PingPacket{ ping := PingPacket{
TS: time.Now(), TS: time.Now(),
} }
b, err := json.Marshal(ping) b, err := json.Marshal(ping)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -29,6 +29,7 @@ func CreateCastPacket(entityID string, skillID int, targetX, targetY float64) Ne
TargetY: targetY, TargetY: targetY,
TargetEntityID: "", // TODO implement targeting entities TargetEntityID: "", // TODO implement targeting entities
} }
b, err := json.Marshal(castPacket) b, err := json.Marshal(castPacket)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -23,6 +23,7 @@ func CreatePlayerConnectionRequestPacket(id string, playerState *d2hero.HeroStat
ID: id, ID: id,
PlayerState: playerState, PlayerState: playerState,
} }
b, err := json.Marshal(playerConnectionRequest) b, err := json.Marshal(playerConnectionRequest)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -22,6 +22,7 @@ func CreatePlayerDisconnectRequestPacket(id string) NetPacket {
playerDisconnectRequest := PlayerDisconnectRequestPacket{ playerDisconnectRequest := PlayerDisconnectRequestPacket{
ID: id, ID: id,
} }
b, err := json.Marshal(playerDisconnectRequest) b, err := json.Marshal(playerDisconnectRequest)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -22,6 +22,7 @@ func CreatePongPacket(id string) NetPacket {
ID: id, ID: id,
TS: time.Now(), TS: time.Now(),
} }
b, err := json.Marshal(pong) b, err := json.Marshal(pong)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -20,6 +20,7 @@ func CreateServerClosedPacket() NetPacket {
serverClosed := ServerClosedPacket{ serverClosed := ServerClosedPacket{
TS: time.Now(), TS: time.Now(),
} }
b, err := json.Marshal(serverClosed) b, err := json.Marshal(serverClosed)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -21,6 +21,7 @@ func CreateUpdateServerInfoPacket(seed int64, playerID string) NetPacket {
Seed: seed, Seed: seed,
PlayerID: playerID, PlayerID: playerID,
} }
b, err := json.Marshal(updateServerInfo) b, err := json.Marshal(updateServerInfo)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -1,3 +1,4 @@
// Package d2tcpclientconnection provides a TCP protocol implementation of a client connection
package d2tcpclientconnection package d2tcpclientconnection
import ( import (

View File

@ -3,12 +3,13 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq"
) )
@ -17,6 +18,7 @@ func main() {
outPath string outPath string
verbose bool verbose bool
) )
flag.StringVar(&outPath, "o", "./output/", "output directory") flag.StringVar(&outPath, "o", "./output/", "output directory")
flag.BoolVar(&verbose, "v", false, "verbose output") flag.BoolVar(&verbose, "v", false, "verbose output")
flag.Parse() flag.Parse()
@ -28,6 +30,7 @@ func main() {
filename := flag.Arg(0) filename := flag.Arg(0)
mpq, err := d2mpq.Load(filename) mpq, err := d2mpq.Load(filename)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -38,6 +41,7 @@ func main() {
} }
_, mpqFile := filepath.Split(strings.Replace(filename, "\\", "/", -1)) _, mpqFile := filepath.Split(strings.Replace(filename, "\\", "/", -1))
for _, filename := range list { for _, filename := range list {
extractFile(mpq, mpqFile, filename, outPath) extractFile(mpq, mpqFile, filename, outPath)
@ -47,7 +51,7 @@ func main() {
} }
} }
func extractFile(mpq d2interface.Archive, mpqFile string, filename string, outPath string) { func extractFile(mpq d2interface.Archive, mpqFile string, filename string, outPath string) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
log.Printf("recovered from panic in file: %s, %v", filename, r) log.Printf("recovered from panic in file: %s, %v", filename, r)
@ -67,6 +71,7 @@ func extractFile(mpq d2interface.Archive, mpqFile string, filename string, outPa
log.Printf("failed to create file: %s, %v", filename, err) log.Printf("failed to create file: %s, %v", filename, err)
return return
} }
defer f.Close() defer f.Close()
buf, err := mpq.ReadFile(filename) buf, err := mpq.ReadFile(filename)
@ -74,6 +79,6 @@ func extractFile(mpq d2interface.Archive, mpqFile string, filename string, outPa
log.Printf("failed to read file: %s, %v", filename, err) log.Printf("failed to read file: %s, %v", filename, err)
return return
} }
f.Write(buf)
f.Write(buf)
} }