mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-10-01 15:46:17 -04:00
fixed all golint type lint errors (#780)
This commit is contained in:
parent
783993470e
commit
e274260787
@ -91,7 +91,7 @@ func (v *linkedNode) insert(other *linkedNode) *linkedNode {
|
|||||||
//nolint:funlen // Makes no sense to split
|
//nolint:funlen // Makes no sense to split
|
||||||
func getPrimes() [][]byte {
|
func getPrimes() [][]byte {
|
||||||
return [][]byte{
|
return [][]byte{
|
||||||
{ //nolint:dupl we're not interested in duplicates here
|
{
|
||||||
// Compression type 0
|
// Compression type 0
|
||||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@ -110,7 +110,7 @@ func getPrimes() [][]byte {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||||
},
|
},
|
||||||
{ //nolint:dupl we're not interested in duplicates here
|
{ //nolint:dupl // it doesnt matter here
|
||||||
// Compression type 1
|
// Compression type 1
|
||||||
0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05,
|
0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05,
|
||||||
0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02,
|
0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02,
|
||||||
@ -129,7 +129,7 @@ func getPrimes() [][]byte {
|
|||||||
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
|
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B,
|
||||||
}, {
|
}, {
|
||||||
// Compression type 2 //nolint:dupl
|
// Compression type 2 //nolint:dupl // it doesnt matter here
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04,
|
0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04,
|
||||||
@ -138,8 +138,8 @@ func getPrimes() [][]byte {
|
|||||||
0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
|
0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01,
|
||||||
0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
|
0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A,
|
||||||
0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01,
|
0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
}, { //nolint:dupl we're not interested in duplicates here
|
}, { //nolint:dupl // it doesnt matter here
|
||||||
// Compression type 3 //nolint:dupl
|
// Compression type 3 //nolint:dupl // it doesnt matter here
|
||||||
0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
|
0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03,
|
||||||
0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
|
0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
|
||||||
0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
@ -156,14 +156,14 @@ func getPrimes() [][]byte {
|
|||||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
|
||||||
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
|
0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
|
||||||
}, { // Compression type 4 //nolint:dupl
|
}, { // Compression type 4 //nolint:dupl // it doesnt matter here
|
||||||
0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
|
0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17,
|
||||||
}, { // Compression type 5 //nolint:dupl
|
}, { // Compression type 5 //nolint:dupl // it doesnt matter here
|
||||||
0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
|
0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82,
|
||||||
0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
|
0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37,
|
||||||
0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
|
0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D,
|
||||||
0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
|
0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18,
|
||||||
}, { //nolint:dupl we're not interested in duplicates here
|
}, { //nolint:dupl // it doesnt matter here
|
||||||
// Compression type 6
|
// Compression type 6
|
||||||
0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@ -174,7 +174,7 @@ func getPrimes() [][]byte {
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x7A, 0x46,
|
0x7A, 0x46,
|
||||||
}, { //nolint:dupl we're not interested in duplicates here
|
}, { //nolint:dupl // it doesnt matter here
|
||||||
// Compression type 7
|
// Compression type 7
|
||||||
0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
|
0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
@ -71,7 +71,7 @@ func (p *Position) RenderOffset() *Vector {
|
|||||||
return p.SubTileOffset().AddScalar(1)
|
return p.SubTileOffset().AddScalar(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// subTileOffset is the offset from the current map tile in sub tiles.
|
// SubTileOffset is the offset from the current map tile in sub tiles.
|
||||||
func (p *Position) SubTileOffset() *Vector {
|
func (p *Position) SubTileOffset() *Vector {
|
||||||
t := p.Tile().Scale(subTilesPerTile)
|
t := p.Tile().Scale(subTilesPerTile)
|
||||||
c := p.Clone()
|
c := p.Clone()
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ImgIndexToRGBA converts the given indices byte slice and palette into
|
||||||
|
// a byte slice of RGBA values
|
||||||
func ImgIndexToRGBA(indexData []byte, palette d2interface.Palette) []byte {
|
func ImgIndexToRGBA(indexData []byte, palette d2interface.Palette) []byte {
|
||||||
bytesPerPixel := 4
|
bytesPerPixel := 4
|
||||||
colorData := make([]byte, len(indexData)*bytesPerPixel)
|
colorData := make([]byte, len(indexData)*bytesPerPixel)
|
||||||
|
@ -2,6 +2,7 @@ package d2util
|
|||||||
|
|
||||||
import "image/color"
|
import "image/color"
|
||||||
|
|
||||||
|
// Color converts an rgba uint32 to a color.RGBA
|
||||||
func Color(rgba uint32) color.RGBA {
|
func Color(rgba uint32) color.RGBA {
|
||||||
result := color.RGBA{}
|
result := color.RGBA{}
|
||||||
a, b, g, r := 0, 1, 2, 3
|
a, b, g, r := 0, 1, 2, 3
|
||||||
|
@ -378,10 +378,12 @@ func (a *Animation) ResetPlayedCount() {
|
|||||||
a.playedCount = 0
|
a.playedCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetEffect sets the draw effect for the animation
|
||||||
func (a *Animation) SetEffect(e d2enum.DrawEffect) {
|
func (a *Animation) SetEffect(e d2enum.DrawEffect) {
|
||||||
a.effect = e
|
a.effect = e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetShadow sets bool for whether or not to draw a shadow
|
||||||
func (a *Animation) SetShadow(shadow bool) {
|
func (a *Animation) SetShadow(shadow bool) {
|
||||||
a.hasShadow = shadow
|
a.hasShadow = shadow
|
||||||
}
|
}
|
||||||
|
@ -369,11 +369,12 @@ func (am *AssetManager) LoadDataDictionary(path string) (*d2txt.DataDictionary,
|
|||||||
//
|
//
|
||||||
// The easy way around this is to not cache d2txt.DataDictionary objects, and just create
|
// The easy way around this is to not cache d2txt.DataDictionary objects, and just create
|
||||||
// a new instance from cached file data if/when we ever need to reload the data dict
|
// a new instance from cached file data if/when we ever need to reload the data dict
|
||||||
if data, err := am.LoadFile(path); err != nil {
|
data, err := am.LoadFile(path)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
|
||||||
return d2txt.LoadDataDictionary(data), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return d2txt.LoadDataDictionary(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadRecords will load the records for the given path into the record manager.
|
// LoadRecords will load the records for the given path into the record manager.
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GuiManager is a GUI widget manager that handles dynamic layout/positioning of widgets
|
||||||
type GuiManager struct {
|
type GuiManager struct {
|
||||||
asset *d2asset.AssetManager
|
asset *d2asset.AssetManager
|
||||||
layout *Layout
|
layout *Layout
|
||||||
|
@ -65,6 +65,7 @@ type Layout struct {
|
|||||||
entries []*layoutEntry
|
entries []*layoutEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateLayout creates a new GUI layout
|
||||||
func CreateLayout(renderer d2interface.Renderer, positionType PositionType, assetManager *d2asset.AssetManager) *Layout {
|
func CreateLayout(renderer d2interface.Renderer, positionType PositionType, assetManager *d2asset.AssetManager) *Layout {
|
||||||
layout := &Layout{
|
layout := &Layout{
|
||||||
renderer: renderer,
|
renderer: renderer,
|
||||||
@ -268,6 +269,7 @@ func (l *Layout) getContentSize() (width, height int) {
|
|||||||
return width, height
|
return width, height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSize returns the layout width and height
|
||||||
func (l *Layout) GetSize() (width, height int) {
|
func (l *Layout) GetSize() (width, height int) {
|
||||||
return l.getSize()
|
return l.getSize()
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ const (
|
|||||||
// static check to ensure Item implements Item
|
// static check to ensure Item implements Item
|
||||||
var _ d2item.Item = &Item{}
|
var _ d2item.Item = &Item{}
|
||||||
|
|
||||||
|
// Item is a representation of a diablo2 item
|
||||||
type Item struct {
|
type Item struct {
|
||||||
factory *ItemFactory
|
factory *ItemFactory
|
||||||
name string
|
name string
|
||||||
@ -249,53 +250,53 @@ func (i *Item) Description() string {
|
|||||||
// affix records, depending on the drop modifier given. If an unsupported
|
// affix records, depending on the drop modifier given. If an unsupported
|
||||||
// drop modifier is supplied, it will attempt to reconcile by picked
|
// drop modifier is supplied, it will attempt to reconcile by picked
|
||||||
// magic affixes as if it were a rare.
|
// magic affixes as if it were a rare.
|
||||||
func (i *Item) applyDropModifier(modifier DropModifier) {
|
func (i *Item) applyDropModifier(modifier dropModifier) {
|
||||||
modifier = i.sanitizeDropModifier(modifier)
|
modifier = i.sanitizeDropModifier(modifier)
|
||||||
|
|
||||||
switch modifier {
|
switch modifier {
|
||||||
case DropModifierUnique:
|
case dropModifierUnique:
|
||||||
i.pickUniqueRecord()
|
i.pickUniqueRecord()
|
||||||
|
|
||||||
if i.UniqueRecord() == nil {
|
if i.UniqueRecord() == nil {
|
||||||
i.applyDropModifier(DropModifierRare)
|
i.applyDropModifier(dropModifierRare)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case DropModifierSet:
|
case dropModifierSet:
|
||||||
i.pickSetRecords()
|
i.pickSetRecords()
|
||||||
|
|
||||||
if i.SetRecord() == nil || i.SetItemRecord() == nil {
|
if i.SetRecord() == nil || i.SetItemRecord() == nil {
|
||||||
i.applyDropModifier(DropModifierRare)
|
i.applyDropModifier(dropModifierRare)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case DropModifierRare, DropModifierMagic:
|
case dropModifierRare, dropModifierMagic:
|
||||||
// the method of picking stays the same for magic/rare
|
// the method of picking stays the same for magic/rare
|
||||||
// but magic gets to pick more, and jewels have a special
|
// but magic gets to pick more, and jewels have a special
|
||||||
// way of picking affixes
|
// way of picking affixes
|
||||||
i.pickMagicAffixes(modifier)
|
i.pickMagicAffixes(modifier)
|
||||||
case DropModifierNone:
|
case dropModifierNone:
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Item) sanitizeDropModifier(modifier DropModifier) DropModifier {
|
func (i *Item) sanitizeDropModifier(modifier dropModifier) dropModifier {
|
||||||
if i.TypeRecord() == nil {
|
if i.TypeRecord() == nil {
|
||||||
i.TypeCode = i.CommonRecord().Type
|
i.TypeCode = i.CommonRecord().Type
|
||||||
}
|
}
|
||||||
|
|
||||||
// should this item always be normal?
|
// should this item always be normal?
|
||||||
if i.TypeRecord().Normal {
|
if i.TypeRecord().Normal {
|
||||||
modifier = DropModifierNone
|
modifier = dropModifierNone
|
||||||
}
|
}
|
||||||
|
|
||||||
// should this item always be magic?
|
// should this item always be magic?
|
||||||
if i.TypeRecord().Magic {
|
if i.TypeRecord().Magic {
|
||||||
modifier = DropModifierMagic
|
modifier = dropModifierMagic
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it isn't allowed to be rare, force it to be magic
|
// if it isn't allowed to be rare, force it to be magic
|
||||||
if modifier == DropModifierRare && !i.TypeRecord().Rare {
|
if modifier == dropModifierRare && !i.TypeRecord().Rare {
|
||||||
modifier = DropModifierMagic
|
modifier = dropModifierMagic
|
||||||
}
|
}
|
||||||
|
|
||||||
return modifier
|
return modifier
|
||||||
@ -320,7 +321,7 @@ func (i *Item) pickSetRecords() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Item) pickMagicAffixes(mod DropModifier) {
|
func (i *Item) pickMagicAffixes(mod dropModifier) {
|
||||||
if i.PrefixCodes == nil {
|
if i.PrefixCodes == nil {
|
||||||
i.PrefixCodes = make([]string, 0)
|
i.PrefixCodes = make([]string, 0)
|
||||||
}
|
}
|
||||||
@ -332,7 +333,7 @@ func (i *Item) pickMagicAffixes(mod DropModifier) {
|
|||||||
totalAffixes, numSuffixes, numPrefixes := 0, 0, 0
|
totalAffixes, numSuffixes, numPrefixes := 0, 0, 0
|
||||||
|
|
||||||
switch mod {
|
switch mod {
|
||||||
case DropModifierRare:
|
case dropModifierRare:
|
||||||
if i.CommonRecord().Type == jewelItemCode {
|
if i.CommonRecord().Type == jewelItemCode {
|
||||||
numPrefixes, numSuffixes = rareJewelPrefixMax, rareJewelSuffixMax
|
numPrefixes, numSuffixes = rareJewelPrefixMax, rareJewelSuffixMax
|
||||||
totalAffixes = rareJewelAffixMax
|
totalAffixes = rareJewelAffixMax
|
||||||
@ -340,7 +341,7 @@ func (i *Item) pickMagicAffixes(mod DropModifier) {
|
|||||||
numPrefixes, numSuffixes = rareItemPrefixMax, rareItemSuffixMax
|
numPrefixes, numSuffixes = rareItemPrefixMax, rareItemSuffixMax
|
||||||
totalAffixes = numPrefixes + numSuffixes
|
totalAffixes = numPrefixes + numSuffixes
|
||||||
}
|
}
|
||||||
case DropModifierMagic:
|
case dropModifierMagic:
|
||||||
numPrefixes, numSuffixes = magicItemPrefixMax, magicItemSuffixMax
|
numPrefixes, numSuffixes = magicItemPrefixMax, magicItemSuffixMax
|
||||||
totalAffixes = numPrefixes + numSuffixes
|
totalAffixes = numPrefixes + numSuffixes
|
||||||
}
|
}
|
||||||
@ -775,31 +776,38 @@ func (i *Item) GetInventoryItemType() d2enum.InventoryItemType {
|
|||||||
return d2enum.InventoryItemTypeItem
|
return d2enum.InventoryItemTypeItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InventoryGridSize returns the size of the item in grid units
|
||||||
func (i *Item) InventoryGridSize() (width, height int) {
|
func (i *Item) InventoryGridSize() (width, height int) {
|
||||||
r := i.CommonRecord()
|
r := i.CommonRecord()
|
||||||
return r.InventoryWidth, r.InventoryHeight
|
return r.InventoryWidth, r.InventoryHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetItemCode returns the item code
|
||||||
func (i *Item) GetItemCode() string {
|
func (i *Item) GetItemCode() string {
|
||||||
return i.CommonRecord().Code
|
return i.CommonRecord().Code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Serialize the item to a byte slize
|
||||||
func (i *Item) Serialize() []byte {
|
func (i *Item) Serialize() []byte {
|
||||||
panic("item serialization not yet implemented")
|
panic("item serialization not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InventoryGridSlot returns the inventory grid slot x and y
|
||||||
func (i *Item) InventoryGridSlot() (x, y int) {
|
func (i *Item) InventoryGridSlot() (x, y int) {
|
||||||
return i.GridX, i.GridY
|
return i.GridX, i.GridY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetInventoryGridSlot sets the inventory grid slot x and y
|
||||||
func (i *Item) SetInventoryGridSlot(x, y int) {
|
func (i *Item) SetInventoryGridSlot(x, y int) {
|
||||||
i.GridX, i.GridY = x, y
|
i.GridX, i.GridY = x, y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetInventoryGridSize returns the inventory grid size in grid units
|
||||||
func (i *Item) GetInventoryGridSize() (x, y int) {
|
func (i *Item) GetInventoryGridSize() (x, y int) {
|
||||||
return i.GridX, i.GridY
|
return i.GridX, i.GridY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Identify sets the identified attribute of the item
|
||||||
func (i *Item) Identify() *Item {
|
func (i *Item) Identify() *Item {
|
||||||
i.attributes.identitified = true
|
i.attributes.identitified = true
|
||||||
return i
|
return i
|
||||||
@ -825,6 +833,8 @@ const (
|
|||||||
reqLevel = "ItemStats1p" // "Required Level:",
|
reqLevel = "ItemStats1p" // "Required Level:",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetItemDescription gets the complete item description as a slice of strings.
|
||||||
|
// This is what is used in the item's hover-tooltip
|
||||||
func (i *Item) GetItemDescription() []string {
|
func (i *Item) GetItemDescription() []string {
|
||||||
lines := make([]string, 0)
|
lines := make([]string, 0)
|
||||||
|
|
||||||
|
@ -18,23 +18,23 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DropModifierBaseProbability = 1024 // base DropModifier probability total
|
dropModifierBaseProbability = 1024 // base dropModifier probability total
|
||||||
)
|
)
|
||||||
|
|
||||||
type DropModifier int
|
type dropModifier int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DropModifierNone DropModifier = iota
|
dropModifierNone dropModifier = iota
|
||||||
DropModifierUnique
|
dropModifierUnique
|
||||||
DropModifierSet
|
dropModifierSet
|
||||||
DropModifierRare
|
dropModifierRare
|
||||||
DropModifierMagic
|
dropModifierMagic
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DynamicItemLevelRange for treasure codes like `armo33`, this code is used to
|
// dynamicItemLevelRange for treasure codes like `armo33`, this code is used to
|
||||||
// select all equivalent items (matching `armo` in this case) with item levels 33,34,35
|
// select all equivalent items (matching `armo` in this case) with item levels 33,34,35
|
||||||
DynamicItemLevelRange = 3
|
dynamicItemLevelRange = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -42,6 +42,7 @@ const (
|
|||||||
goldItemCode = "gld"
|
goldItemCode = "gld"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewItemFactory creates a new ItemFactory instance
|
||||||
func NewItemFactory(asset *d2asset.AssetManager) (*ItemFactory, error) {
|
func NewItemFactory(asset *d2asset.AssetManager) (*ItemFactory, error) {
|
||||||
itemFactory := &ItemFactory{
|
itemFactory := &ItemFactory{
|
||||||
asset: asset,
|
asset: asset,
|
||||||
@ -79,6 +80,7 @@ func (f *ItemFactory) SetSeed(seed int64) {
|
|||||||
f.Seed = seed
|
f.Seed = seed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewItem creates a new item instance from the given codes
|
||||||
func (f *ItemFactory) NewItem(codes ...string) (*Item, error) {
|
func (f *ItemFactory) NewItem(codes ...string) (*Item, error) {
|
||||||
var item *Item
|
var item *Item
|
||||||
|
|
||||||
@ -173,17 +175,17 @@ func (f *ItemFactory) NewProperty(code string, values ...int) *Property {
|
|||||||
return result.init()
|
return result.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *ItemFactory) rollDropModifier(tcr *d2records.TreasureClassRecord) DropModifier {
|
func (f *ItemFactory) rollDropModifier(tcr *d2records.TreasureClassRecord) dropModifier {
|
||||||
modMap := map[int]DropModifier{
|
modMap := map[int]dropModifier{
|
||||||
0: DropModifierNone,
|
0: dropModifierNone,
|
||||||
1: DropModifierUnique,
|
1: dropModifierUnique,
|
||||||
2: DropModifierSet,
|
2: dropModifierSet,
|
||||||
3: DropModifierRare,
|
3: dropModifierRare,
|
||||||
4: DropModifierMagic,
|
4: dropModifierMagic,
|
||||||
}
|
}
|
||||||
|
|
||||||
dropModifiers := []int{
|
dropModifiers := []int{
|
||||||
DropModifierBaseProbability,
|
dropModifierBaseProbability,
|
||||||
tcr.FreqUnique,
|
tcr.FreqUnique,
|
||||||
tcr.FreqSet,
|
tcr.FreqSet,
|
||||||
tcr.FreqRare,
|
tcr.FreqRare,
|
||||||
@ -206,7 +208,7 @@ func (f *ItemFactory) rollDropModifier(tcr *d2records.TreasureClassRecord) DropM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DropModifierNone
|
return dropModifierNone
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *ItemFactory) rollTreasurePick(tcr *d2records.TreasureClassRecord) *d2records.Treasure {
|
func (f *ItemFactory) rollTreasurePick(tcr *d2records.TreasureClassRecord) *d2records.Treasure {
|
||||||
@ -396,7 +398,7 @@ func (f *ItemFactory) resolveDynamicTreasureCode(code string) []*d2records.ItemC
|
|||||||
for idx := range equivList {
|
for idx := range equivList {
|
||||||
record := equivList[idx]
|
record := equivList[idx]
|
||||||
minLevel := numericComponent
|
minLevel := numericComponent
|
||||||
maxLevel := minLevel + DynamicItemLevelRange
|
maxLevel := minLevel + dynamicItemLevelRange
|
||||||
|
|
||||||
if record.Level >= minLevel && record.Level < maxLevel {
|
if record.Level >= minLevel && record.Level < maxLevel {
|
||||||
result = append(result, record)
|
result = append(result, record)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package d2item
|
package d2item
|
||||||
|
|
||||||
|
// Equipper is an interface for something that can equip items
|
||||||
type Equipper interface {
|
type Equipper interface {
|
||||||
EquippedItems() []Item
|
EquippedItems() []Item
|
||||||
CarriedItems() []Item
|
CarriedItems() []Item
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Package d2object implements objects placed on the map and their functionality
|
// Package d2mapentity implements map entities
|
||||||
package d2mapentity
|
package d2mapentity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package d2records
|
package d2records
|
||||||
|
|
||||||
|
// Belts stores all of the BeltRecords
|
||||||
type Belts map[string]*BeltRecord
|
type Belts map[string]*BeltRecord
|
||||||
|
|
||||||
|
// BeltRecord is a representation of the belt ui-panel dimensions/positioning
|
||||||
type BeltRecord struct {
|
type BeltRecord struct {
|
||||||
Name string
|
Name string
|
||||||
NumBoxes int
|
NumBoxes int
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package d2records
|
package d2records
|
||||||
|
|
||||||
|
// Colors is a map of ColorRecords
|
||||||
type Colors map[string]*ColorRecord
|
type Colors map[string]*ColorRecord
|
||||||
|
|
||||||
|
// ColorRecord is a representation of a color transform
|
||||||
type ColorRecord struct {
|
type ColorRecord struct {
|
||||||
TransformColor string
|
TransformColor string
|
||||||
Code string
|
Code string
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// d2records provides a RecordManager implementation which is used to parse
|
// Package 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
|
// 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.
|
// parsed into slices or maps of structs. There is a struct type defined for each txt file.
|
||||||
//
|
//
|
||||||
|
@ -6,7 +6,7 @@ import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
|||||||
// for each level for each character class
|
// for each level for each character class
|
||||||
type ExperienceBreakpoints map[int]*ExperienceBreakpointsRecord
|
type ExperienceBreakpoints map[int]*ExperienceBreakpointsRecord
|
||||||
|
|
||||||
// Type ExperienceMaxLevels defines the max character levels
|
// ExperienceMaxLevels defines the max character levels
|
||||||
type ExperienceMaxLevels map[d2enum.Hero]int
|
type ExperienceMaxLevels map[d2enum.Hero]int
|
||||||
|
|
||||||
// ExperienceBreakpointsRecord describes the experience points required to
|
// ExperienceBreakpointsRecord describes the experience points required to
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package d2records
|
package d2records
|
||||||
|
|
||||||
|
// Gamble is a map of GambleRecords
|
||||||
type Gamble map[string]*GambleRecord
|
type Gamble map[string]*GambleRecord
|
||||||
|
|
||||||
|
// GambleRecord is a representation of an item type that can be gambled for at vendors
|
||||||
type GambleRecord struct {
|
type GambleRecord struct {
|
||||||
Name string
|
Name string
|
||||||
Code string
|
Code string
|
||||||
|
@ -62,6 +62,7 @@ type ItemAffixCommonRecord struct {
|
|||||||
Transform bool
|
Transform bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddMember adds an affix to the group
|
||||||
func (g *ItemAffixCommonGroup) AddMember(a *ItemAffixCommonRecord) {
|
func (g *ItemAffixCommonGroup) AddMember(a *ItemAffixCommonRecord) {
|
||||||
if g.Members == nil {
|
if g.Members == nil {
|
||||||
g.Members = make(map[string]*ItemAffixCommonRecord)
|
g.Members = make(map[string]*ItemAffixCommonRecord)
|
||||||
@ -70,6 +71,7 @@ func (g *ItemAffixCommonGroup) AddMember(a *ItemAffixCommonRecord) {
|
|||||||
g.Members[a.Name] = a
|
g.Members[a.Name] = a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTotalFrequency returns the cumulative frequency of the affix group
|
||||||
func (g *ItemAffixCommonGroup) GetTotalFrequency() int {
|
func (g *ItemAffixCommonGroup) GetTotalFrequency() int {
|
||||||
total := 0
|
total := 0
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package d2records
|
|||||||
// ItemRatios holds all of the ItemRatioRecords from ItemRatio.txt
|
// ItemRatios holds all of the ItemRatioRecords from ItemRatio.txt
|
||||||
type ItemRatios map[string]*ItemRatioRecord
|
type ItemRatios map[string]*ItemRatioRecord
|
||||||
|
|
||||||
// A helper type for item drop calculation
|
// DropRatioInfo is a helper struct for item drop calculation
|
||||||
type DropRatioInfo struct {
|
type DropRatioInfo struct {
|
||||||
Frequency int
|
Frequency int
|
||||||
Divisor int
|
Divisor int
|
||||||
|
@ -15,39 +15,39 @@ func monsterPropertiesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
|
|||||||
ID: d.String("Id"),
|
ID: d.String("Id"),
|
||||||
|
|
||||||
Properties: struct {
|
Properties: struct {
|
||||||
Normal [NumMonProps]*MonProp
|
Normal [numMonProps]*MonProp
|
||||||
Nightmare [NumMonProps]*MonProp
|
Nightmare [numMonProps]*MonProp
|
||||||
Hell [NumMonProps]*MonProp
|
Hell [numMonProps]*MonProp
|
||||||
}{
|
}{
|
||||||
[NumMonProps]*MonProp{},
|
[numMonProps]*MonProp{},
|
||||||
[NumMonProps]*MonProp{},
|
[numMonProps]*MonProp{},
|
||||||
[NumMonProps]*MonProp{},
|
[numMonProps]*MonProp{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx := 1; idx <= NumMonProps; idx++ {
|
for idx := 1; idx <= numMonProps; idx++ {
|
||||||
record.Properties.Normal[idx-1] = &MonProp{
|
record.Properties.Normal[idx-1] = &MonProp{
|
||||||
Code: d.String(fmt.Sprintf(FmtProp, idx, FmtNormal)),
|
Code: d.String(fmt.Sprintf(fmtProp, idx, fmtNormal)),
|
||||||
Param: d.String(fmt.Sprintf(FmtPar, idx, FmtNormal)),
|
Param: d.String(fmt.Sprintf(fmtPar, idx, fmtNormal)),
|
||||||
Chance: d.Number(fmt.Sprintf(FmtChance, idx, FmtNormal)),
|
Chance: d.Number(fmt.Sprintf(fmtChance, idx, fmtNormal)),
|
||||||
Min: d.Number(fmt.Sprintf(FmtMin, idx, FmtNormal)),
|
Min: d.Number(fmt.Sprintf(fmtMin, idx, fmtNormal)),
|
||||||
Max: d.Number(fmt.Sprintf(FmtMax, idx, FmtNormal)),
|
Max: d.Number(fmt.Sprintf(fmtMax, idx, fmtNormal)),
|
||||||
}
|
}
|
||||||
|
|
||||||
record.Properties.Nightmare[idx-1] = &MonProp{
|
record.Properties.Nightmare[idx-1] = &MonProp{
|
||||||
Code: d.String(fmt.Sprintf(FmtProp, idx, FmtNightmare)),
|
Code: d.String(fmt.Sprintf(fmtProp, idx, fmtNightmare)),
|
||||||
Param: d.String(fmt.Sprintf(FmtPar, idx, FmtNightmare)),
|
Param: d.String(fmt.Sprintf(fmtPar, idx, fmtNightmare)),
|
||||||
Chance: d.Number(fmt.Sprintf(FmtChance, idx, FmtNightmare)),
|
Chance: d.Number(fmt.Sprintf(fmtChance, idx, fmtNightmare)),
|
||||||
Min: d.Number(fmt.Sprintf(FmtMin, idx, FmtNightmare)),
|
Min: d.Number(fmt.Sprintf(fmtMin, idx, fmtNightmare)),
|
||||||
Max: d.Number(fmt.Sprintf(FmtMax, idx, FmtNightmare)),
|
Max: d.Number(fmt.Sprintf(fmtMax, idx, fmtNightmare)),
|
||||||
}
|
}
|
||||||
|
|
||||||
record.Properties.Hell[idx-1] = &MonProp{
|
record.Properties.Hell[idx-1] = &MonProp{
|
||||||
Code: d.String(fmt.Sprintf(FmtProp, idx, FmtHell)),
|
Code: d.String(fmt.Sprintf(fmtProp, idx, fmtHell)),
|
||||||
Param: d.String(fmt.Sprintf(FmtPar, idx, FmtHell)),
|
Param: d.String(fmt.Sprintf(fmtPar, idx, fmtHell)),
|
||||||
Chance: d.Number(fmt.Sprintf(FmtChance, idx, FmtHell)),
|
Chance: d.Number(fmt.Sprintf(fmtChance, idx, fmtHell)),
|
||||||
Min: d.Number(fmt.Sprintf(FmtMin, idx, FmtHell)),
|
Min: d.Number(fmt.Sprintf(fmtMin, idx, fmtHell)),
|
||||||
Max: d.Number(fmt.Sprintf(FmtMax, idx, FmtHell)),
|
Max: d.Number(fmt.Sprintf(fmtMax, idx, fmtHell)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package d2records
|
package d2records
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NumMonProps = 6
|
numMonProps = 6
|
||||||
FmtProp = "prop%d%s"
|
fmtProp = "prop%d%s"
|
||||||
FmtChance = "chance%d%s"
|
fmtChance = "chance%d%s"
|
||||||
FmtPar = "par%d%s"
|
fmtPar = "par%d%s"
|
||||||
FmtMin = "min%d%s"
|
fmtMin = "min%d%s"
|
||||||
FmtMax = "max%d%s"
|
fmtMax = "max%d%s"
|
||||||
FmtNormal = ""
|
fmtNormal = ""
|
||||||
FmtNightmare = " (N)"
|
fmtNightmare = " (N)"
|
||||||
FmtHell = " (H)"
|
fmtHell = " (H)"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MonsterProperties stores all of the MonPropRecords
|
// MonsterProperties stores all of the MonPropRecords
|
||||||
@ -20,9 +20,9 @@ type MonPropRecord struct {
|
|||||||
ID string
|
ID string
|
||||||
|
|
||||||
Properties struct {
|
Properties struct {
|
||||||
Normal [NumMonProps]*MonProp
|
Normal [numMonProps]*MonProp
|
||||||
Nightmare [NumMonProps]*MonProp
|
Nightmare [numMonProps]*MonProp
|
||||||
Hell [NumMonProps]*MonProp
|
Hell [numMonProps]*MonProp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package d2records
|
package d2records
|
||||||
|
|
||||||
// MonTypes stores all of the MonTypeRecords
|
// MonsterTypes stores all of the MonTypeRecords
|
||||||
type MonsterTypes map[string]*MonTypeRecord
|
type MonsterTypes map[string]*MonTypeRecord
|
||||||
|
|
||||||
// MonTypeRecord is a representation of a single row of MonType.txt.
|
// MonTypeRecord is a representation of a single row of MonType.txt.
|
||||||
|
@ -49,10 +49,11 @@ type MonUModRecord struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PickFreq restricts the range of modifiers that can spawn ...
|
||||||
type PickFreq struct {
|
type PickFreq struct {
|
||||||
// Champion pick frequency
|
// ...on champion monsters
|
||||||
Champion int
|
Champion int
|
||||||
|
|
||||||
// Unique pick frequency
|
// ... on unique monsters
|
||||||
Unique int
|
Unique int
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package d2records
|
|||||||
// ObjectDetails stores all of the ObjectDetailRecords
|
// ObjectDetails stores all of the ObjectDetailRecords
|
||||||
type ObjectDetails map[int]*ObjectDetailsRecord
|
type ObjectDetails map[int]*ObjectDetailsRecord
|
||||||
|
|
||||||
// An ObjectRecord represents the settings for one type of object from objects.txt
|
// ObjectDetailsRecord represents the settings for one type of object from objects.txt
|
||||||
type ObjectDetailsRecord struct {
|
type ObjectDetailsRecord struct {
|
||||||
Index int // Line number in file, this is the actual index used for objects
|
Index int // Line number in file, this is the actual index used for objects
|
||||||
FrameCount [8]int // how many frames does this mode have, 0 = skip
|
FrameCount [8]int // how many frames does this mode have, 0 = skip
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package d2records
|
package d2records
|
||||||
|
|
||||||
|
// ObjectModes is a map of ObjectModeRecords
|
||||||
type ObjectModes map[string]*ObjectModeRecord
|
type ObjectModes map[string]*ObjectModeRecord
|
||||||
|
|
||||||
|
// ObjectModeRecord is a representation of an animation mode for an object
|
||||||
type ObjectModeRecord struct {
|
type ObjectModeRecord struct {
|
||||||
Name string
|
Name string
|
||||||
Token string
|
Token string
|
||||||
|
@ -24,6 +24,7 @@ type RunesRecord struct {
|
|||||||
Properties []*RunewordProperty
|
Properties []*RunewordProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunewordProperty is a representation of a stat possessed by this runeword
|
||||||
type RunewordProperty struct {
|
type RunewordProperty struct {
|
||||||
// Code is the property code
|
// Code is the property code
|
||||||
Code string
|
Code string
|
||||||
|
@ -30,6 +30,7 @@ type SetRecord struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetProperty represents a property possessed by the set
|
||||||
type SetProperty struct {
|
type SetProperty struct {
|
||||||
// Code is an ID pointer of a property from Properties.txt,
|
// Code is an ID pointer of a property from Properties.txt,
|
||||||
// these columns control each of the eight different full set modifiers a set item can grant you
|
// these columns control each of the eight different full set modifiers a set item can grant you
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package d2records
|
package d2records
|
||||||
|
|
||||||
// Sounds stores all of the SoundEntries
|
// SoundDetails is a map of the SoundEntries
|
||||||
type SoundDetails map[string]*SoundDetailsRecord
|
type SoundDetails map[string]*SoundDetailsRecord
|
||||||
|
|
||||||
// SoundDetailsRecord represents a sound entry
|
// SoundDetailsRecord represents a sound entry
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package d2records
|
package d2records
|
||||||
|
|
||||||
// StorePages struct contains all store page records
|
// StorePages is a map of all store page records
|
||||||
type StorePages map[string]*StorePageRecord
|
type StorePages map[string]*StorePageRecord
|
||||||
|
|
||||||
// StorePageRecords represent a row in the storepage.txt file
|
// StorePageRecord represent a row in the storepage.txt file
|
||||||
type StorePageRecord struct {
|
type StorePageRecord struct {
|
||||||
StorePage string
|
StorePage string
|
||||||
Code string
|
Code string
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2stats"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2stats"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewStatFactory creates a new stat factory instance
|
||||||
func NewStatFactory(asset *d2asset.AssetManager) (*StatFactory, error) {
|
func NewStatFactory(asset *d2asset.AssetManager) (*StatFactory, error) {
|
||||||
factory := &StatFactory{asset: asset}
|
factory := &StatFactory{asset: asset}
|
||||||
|
|
||||||
|
@ -513,6 +513,7 @@ func (v *CharacterSelect) onOkButtonClicked() {
|
|||||||
v.navigator.ToCreateGame(v.gameStates[v.selectedCharacter].FilePath, v.connectionType, v.connectionHost)
|
v.navigator.ToCreateGame(v.gameStates[v.selectedCharacter].FilePath, v.connectionType, v.connectionHost)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnUnload candles cleanup when this screen is closed
|
||||||
func (v *CharacterSelect) OnUnload() error {
|
func (v *CharacterSelect) OnUnload() error {
|
||||||
if err := v.inputManager.UnbindHandler(v); err != nil { // TODO: hack
|
if err := v.inputManager.UnbindHandler(v); err != nil { // TODO: hack
|
||||||
return err
|
return err
|
||||||
|
@ -331,6 +331,7 @@ func (met *MapEngineTest) Render(screen d2interface.Surface) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnMouseMove is the mouse move handler
|
||||||
func (met *MapEngineTest) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
func (met *MapEngineTest) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
||||||
mx, my := event.X(), event.Y()
|
mx, my := event.X(), event.Y()
|
||||||
met.lastMouseX = mx
|
met.lastMouseX = mx
|
||||||
|
@ -360,6 +360,7 @@ func (m *EscapeMenu) addEnumLabel(l *layout, optID optionID, text string, values
|
|||||||
l.actionableElements = append(l.actionableElements, label)
|
l.actionableElements = append(l.actionableElements, label)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnLoad loads the necessary files for the escape menu
|
||||||
func (m *EscapeMenu) OnLoad() {
|
func (m *EscapeMenu) OnLoad() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -369,6 +370,7 @@ func (m *EscapeMenu) OnLoad() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnEscKey is called when the escape key is pressed
|
||||||
func (m *EscapeMenu) OnEscKey() {
|
func (m *EscapeMenu) OnEscKey() {
|
||||||
// note: original D2 returns straight to the game from however deep in the menu we are
|
// note: original D2 returns straight to the game from however deep in the menu we are
|
||||||
switch m.currentLayout {
|
switch m.currentLayout {
|
||||||
@ -491,6 +493,7 @@ func (m *EscapeMenu) onEnterKey() {
|
|||||||
m.layouts[m.currentLayout].actionableElements[m.layouts[m.currentLayout].currentEl].Trigger()
|
m.layouts[m.currentLayout].actionableElements[m.layouts[m.currentLayout].currentEl].Trigger()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsOpen returns whether the escape menu is open (visible) or not
|
||||||
func (m *EscapeMenu) IsOpen() bool {
|
func (m *EscapeMenu) IsOpen() bool {
|
||||||
return m.isOpen
|
return m.isOpen
|
||||||
}
|
}
|
||||||
|
@ -47,10 +47,10 @@ const (
|
|||||||
|
|
||||||
// GameControls represents the game's controls on the screen
|
// GameControls represents the game's controls on the screen
|
||||||
type GameControls struct {
|
type GameControls struct {
|
||||||
actionableRegions []ActionableRegion
|
actionableRegions []actionableRegion
|
||||||
asset *d2asset.AssetManager
|
asset *d2asset.AssetManager
|
||||||
renderer d2interface.Renderer // TODO: This shouldn't be a dependency
|
renderer d2interface.Renderer // TODO: This shouldn't be a dependency
|
||||||
inputListener InputCallbackListener
|
inputListener inputCallbackListener
|
||||||
hero *d2mapentity.Player
|
hero *d2mapentity.Player
|
||||||
heroState *d2hero.HeroStateFactory
|
heroState *d2hero.HeroStateFactory
|
||||||
mapEngine *d2mapengine.MapEngine
|
mapEngine *d2mapengine.MapEngine
|
||||||
@ -83,11 +83,11 @@ type GameControls struct {
|
|||||||
isSinglePlayer bool
|
isSinglePlayer bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionableType int
|
type actionableType int
|
||||||
|
|
||||||
type ActionableRegion struct {
|
type actionableRegion struct {
|
||||||
ActionableTypeID ActionableType
|
actionableTypeID actionableType
|
||||||
Rect d2geom.Rectangle
|
rect d2geom.Rectangle
|
||||||
}
|
}
|
||||||
|
|
||||||
// SkillResource represents a Skill with its corresponding icon sprite, path to DC6 file and icon number.
|
// SkillResource represents a Skill with its corresponding icon sprite, path to DC6 file and icon number.
|
||||||
@ -101,7 +101,7 @@ type SkillResource struct {
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Since they require special handling, not considering (1) globes, (2) content of the mini panel, (3) belt
|
// Since they require special handling, not considering (1) globes, (2) content of the mini panel, (3) belt
|
||||||
leftSkill ActionableType = iota
|
leftSkill actionableType = iota
|
||||||
newStats
|
newStats
|
||||||
xp
|
xp
|
||||||
walkRun
|
walkRun
|
||||||
@ -128,7 +128,7 @@ func NewGameControls(
|
|||||||
mapEngine *d2mapengine.MapEngine,
|
mapEngine *d2mapengine.MapEngine,
|
||||||
escapeMenu *EscapeMenu,
|
escapeMenu *EscapeMenu,
|
||||||
mapRenderer *d2maprenderer.MapRenderer,
|
mapRenderer *d2maprenderer.MapRenderer,
|
||||||
inputListener InputCallbackListener,
|
inputListener inputCallbackListener,
|
||||||
term d2interface.Terminal,
|
term d2interface.Terminal,
|
||||||
ui *d2ui.UIManager,
|
ui *d2ui.UIManager,
|
||||||
guiManager *d2gui.GuiManager,
|
guiManager *d2gui.GuiManager,
|
||||||
@ -197,7 +197,7 @@ func NewGameControls(
|
|||||||
nameLabel: hoverLabel,
|
nameLabel: hoverLabel,
|
||||||
zoneChangeText: zoneLabel,
|
zoneChangeText: zoneLabel,
|
||||||
hpManaStatsLabel: globeStatsLabel,
|
hpManaStatsLabel: globeStatsLabel,
|
||||||
actionableRegions: []ActionableRegion{
|
actionableRegions: []actionableRegion{
|
||||||
{leftSkill, d2geom.Rectangle{Left: 115, Top: 550, Width: 50, Height: 50}},
|
{leftSkill, d2geom.Rectangle{Left: 115, Top: 550, Width: 50, Height: 50}},
|
||||||
{newStats, d2geom.Rectangle{Left: 206, Top: 563, Width: 30, Height: 30}},
|
{newStats, d2geom.Rectangle{Left: 206, Top: 563, Width: 30, Height: 30}},
|
||||||
{xp, d2geom.Rectangle{Left: 253, Top: 560, Width: 125, Height: 5}},
|
{xp, d2geom.Rectangle{Left: 253, Top: 560, Width: 125, Height: 5}},
|
||||||
@ -431,8 +431,8 @@ func (g *GameControls) OnMouseMove(event d2interface.MouseMoveEvent) bool {
|
|||||||
|
|
||||||
for i := range g.actionableRegions {
|
for i := range g.actionableRegions {
|
||||||
// Mouse over a game control element
|
// Mouse over a game control element
|
||||||
if g.actionableRegions[i].Rect.IsInRect(mx, my) {
|
if g.actionableRegions[i].rect.IsInRect(mx, my) {
|
||||||
g.onHoverActionable(g.actionableRegions[i].ActionableTypeID)
|
g.onHoverActionable(g.actionableRegions[i].actionableTypeID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,8 +445,8 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
|
|||||||
|
|
||||||
for i := range g.actionableRegions {
|
for i := range g.actionableRegions {
|
||||||
// If click is on a game control element
|
// If click is on a game control element
|
||||||
if g.actionableRegions[i].Rect.IsInRect(mx, my) {
|
if g.actionableRegions[i].rect.IsInRect(mx, my) {
|
||||||
g.onClickActionable(g.actionableRegions[i].ActionableTypeID)
|
g.onClickActionable(g.actionableRegions[i].actionableTypeID)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -890,7 +890,7 @@ func (g *GameControls) Render(target d2interface.Surface) error {
|
|||||||
strPanelHealth := fmt.Sprintf(fmtHealth, healthCurr, healthMax)
|
strPanelHealth := fmt.Sprintf(fmtHealth, healthCurr, healthMax)
|
||||||
|
|
||||||
// Display current hp and mana stats hpGlobe or manaGlobe region is clicked
|
// Display current hp and mana stats hpGlobe or manaGlobe region is clicked
|
||||||
if g.actionableRegions[hpGlobe].Rect.IsInRect(mx, my) || g.hpStatsIsVisible {
|
if g.actionableRegions[hpGlobe].rect.IsInRect(mx, my) || g.hpStatsIsVisible {
|
||||||
g.hpManaStatsLabel.SetText(strPanelHealth)
|
g.hpManaStatsLabel.SetText(strPanelHealth)
|
||||||
g.hpManaStatsLabel.SetPosition(15, 487)
|
g.hpManaStatsLabel.SetPosition(15, 487)
|
||||||
g.hpManaStatsLabel.Render(target)
|
g.hpManaStatsLabel.Render(target)
|
||||||
@ -901,7 +901,7 @@ func (g *GameControls) Render(target d2interface.Surface) error {
|
|||||||
manaCurr, manaMax := int(g.hero.Stats.Mana), int(g.hero.Stats.MaxMana)
|
manaCurr, manaMax := int(g.hero.Stats.Mana), int(g.hero.Stats.MaxMana)
|
||||||
strPanelMana := fmt.Sprintf(fmtMana, manaCurr, manaMax)
|
strPanelMana := fmt.Sprintf(fmtMana, manaCurr, manaMax)
|
||||||
|
|
||||||
if g.actionableRegions[manaGlobe].Rect.IsInRect(mx, my) || g.manaStatsIsVisible {
|
if g.actionableRegions[manaGlobe].rect.IsInRect(mx, my) || g.manaStatsIsVisible {
|
||||||
g.hpManaStatsLabel.SetText(strPanelMana)
|
g.hpManaStatsLabel.SetText(strPanelMana)
|
||||||
// In case if the mana value gets higher, we need to shift the label to the left a little, hence widthManaLabel.
|
// In case if the mana value gets higher, we need to shift the label to the left a little, hence widthManaLabel.
|
||||||
widthManaLabel, _ := g.hpManaStatsLabel.GetSize()
|
widthManaLabel, _ := g.hpManaStatsLabel.GetSize()
|
||||||
@ -915,63 +915,63 @@ func (g *GameControls) Render(target d2interface.Surface) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Minipanel is closed and minipanel button is hovered.
|
// Minipanel is closed and minipanel button is hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[miniPnl].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[miniPnl].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("panelcmini")) //"Close Mini Panel"
|
g.nameLabel.SetText(d2tbl.TranslateString("panelcmini")) //"Close Mini Panel"
|
||||||
g.nameLabel.SetPosition(399, 544)
|
g.nameLabel.SetPosition(399, 544)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minipanel is open and minipanel button is hovered.
|
// Minipanel is open and minipanel button is hovered.
|
||||||
if !g.miniPanel.IsOpen() && g.actionableRegions[miniPnl].Rect.IsInRect(mx, my) {
|
if !g.miniPanel.IsOpen() && g.actionableRegions[miniPnl].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("panelmini")) //"Open Mini Panel"
|
g.nameLabel.SetText(d2tbl.TranslateString("panelmini")) //"Open Mini Panel"
|
||||||
g.nameLabel.SetPosition(399, 544)
|
g.nameLabel.SetPosition(399, 544)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display character tooltip when hovered.
|
// Display character tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelCharacter].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelCharacter].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("minipanelchar")) //"Character" no hotkey
|
g.nameLabel.SetText(d2tbl.TranslateString("minipanelchar")) //"Character" no hotkey
|
||||||
g.nameLabel.SetPosition(340, 510)
|
g.nameLabel.SetPosition(340, 510)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display inventory tooltip when hovered.
|
// Display inventory tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelInventory].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelInventory].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("minipanelinv")) //"Inventory" no hotkey
|
g.nameLabel.SetText(d2tbl.TranslateString("minipanelinv")) //"Inventory" no hotkey
|
||||||
g.nameLabel.SetPosition(360, 510)
|
g.nameLabel.SetPosition(360, 510)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display skill tree tooltip when hovered.
|
// Display skill tree tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelSkillTree].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelSkillTree].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("minipaneltree")) //"Skill Treee" no hotkey
|
g.nameLabel.SetText(d2tbl.TranslateString("minipaneltree")) //"Skill Treee" no hotkey
|
||||||
g.nameLabel.SetPosition(380, 510)
|
g.nameLabel.SetPosition(380, 510)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display automap tooltip when hovered.
|
// Display automap tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelAutomap].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelAutomap].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("minipanelautomap")) //"Automap" no hotkey
|
g.nameLabel.SetText(d2tbl.TranslateString("minipanelautomap")) //"Automap" no hotkey
|
||||||
g.nameLabel.SetPosition(400, 510)
|
g.nameLabel.SetPosition(400, 510)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display message log tooltip when hovered.
|
// Display message log tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelMessageLog].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelMessageLog].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("minipanelmessage")) //"Message Log" no hotkey
|
g.nameLabel.SetText(d2tbl.TranslateString("minipanelmessage")) //"Message Log" no hotkey
|
||||||
g.nameLabel.SetPosition(420, 510)
|
g.nameLabel.SetPosition(420, 510)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display quest log tooltip when hovered.
|
// Display quest log tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelQuestLog].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelQuestLog].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("minipanelquest")) //"Quest Log" no hotkey
|
g.nameLabel.SetText(d2tbl.TranslateString("minipanelquest")) //"Quest Log" no hotkey
|
||||||
g.nameLabel.SetPosition(440, 510)
|
g.nameLabel.SetPosition(440, 510)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display game menu tooltip when hovered.
|
// Display game menu tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelGameMenu].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[miniPanelGameMenu].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("minipanelmenubtn")) //"Game Menu (Esc)" // the (Esc) is hardcoded in.
|
g.nameLabel.SetText(d2tbl.TranslateString("minipanelmenubtn")) //"Game Menu (Esc)" // the (Esc) is hardcoded in.
|
||||||
g.nameLabel.SetPosition(460, 510)
|
g.nameLabel.SetPosition(460, 510)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
@ -983,20 +983,20 @@ func (g *GameControls) Render(target d2interface.Surface) error {
|
|||||||
strPanelStamina := fmt.Sprintf(fmtStamina, staminaCurr, staminaMax)
|
strPanelStamina := fmt.Sprintf(fmtStamina, staminaCurr, staminaMax)
|
||||||
|
|
||||||
// Display stamina tooltip when hovered.
|
// Display stamina tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[stamina].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[stamina].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(strPanelStamina)
|
g.nameLabel.SetText(strPanelStamina)
|
||||||
g.nameLabel.SetPosition(320, 535)
|
g.nameLabel.SetPosition(320, 535)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display run/walk tooltip when hovered. Note that whether the player is walking or running, the tooltip is the same in Diablo 2.
|
// Display run/walk tooltip when hovered. Note that whether the player is walking or running, the tooltip is the same in Diablo 2.
|
||||||
if g.actionableRegions[walkRun].Rect.IsInRect(mx, my) && !g.hero.IsRunToggled() {
|
if g.actionableRegions[walkRun].rect.IsInRect(mx, my) && !g.hero.IsRunToggled() {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("RunOn")) //"Run" no hotkeys
|
g.nameLabel.SetText(d2tbl.TranslateString("RunOn")) //"Run" no hotkeys
|
||||||
g.nameLabel.SetPosition(263, 563)
|
g.nameLabel.SetPosition(263, 563)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.actionableRegions[walkRun].Rect.IsInRect(mx, my) && g.hero.IsRunToggled() {
|
if g.actionableRegions[walkRun].rect.IsInRect(mx, my) && g.hero.IsRunToggled() {
|
||||||
g.nameLabel.SetText(d2tbl.TranslateString("RunOff")) //"Walk" no hotkeys
|
g.nameLabel.SetText(d2tbl.TranslateString("RunOff")) //"Walk" no hotkeys
|
||||||
g.nameLabel.SetPosition(263, 563)
|
g.nameLabel.SetPosition(263, 563)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
@ -1012,7 +1012,7 @@ func (g *GameControls) Render(target d2interface.Surface) error {
|
|||||||
strPanelExp := fmt.Sprintf(fmtExp, expCurr, expMax)
|
strPanelExp := fmt.Sprintf(fmtExp, expCurr, expMax)
|
||||||
|
|
||||||
// Display experience tooltip when hovered.
|
// Display experience tooltip when hovered.
|
||||||
if g.miniPanel.IsOpen() && g.actionableRegions[xp].Rect.IsInRect(mx, my) {
|
if g.miniPanel.IsOpen() && g.actionableRegions[xp].rect.IsInRect(mx, my) {
|
||||||
g.nameLabel.SetText(strPanelExp)
|
g.nameLabel.SetText(strPanelExp)
|
||||||
g.nameLabel.SetPosition(255, 535)
|
g.nameLabel.SetPosition(255, 535)
|
||||||
g.nameLabel.Render(target)
|
g.nameLabel.Render(target)
|
||||||
@ -1059,7 +1059,7 @@ func (g *GameControls) ToggleManaStats() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handles what to do when an actionable is hovered
|
// Handles what to do when an actionable is hovered
|
||||||
func (g *GameControls) onHoverActionable(item ActionableType) {
|
func (g *GameControls) onHoverActionable(item actionableType) {
|
||||||
switch item {
|
switch item {
|
||||||
case leftSkill:
|
case leftSkill:
|
||||||
return
|
return
|
||||||
@ -1096,12 +1096,12 @@ func (g *GameControls) onHoverActionable(item ActionableType) {
|
|||||||
case miniPanelGameMenu:
|
case miniPanelGameMenu:
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
log.Printf("Unrecognized ActionableType(%d) being hovered\n", item)
|
log.Printf("Unrecognized actionableType(%d) being hovered\n", item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles what to do when an actionable is clicked
|
// Handles what to do when an actionable is clicked
|
||||||
func (g *GameControls) onClickActionable(item ActionableType) {
|
func (g *GameControls) onClickActionable(item actionableType) {
|
||||||
switch item {
|
switch item {
|
||||||
case leftSkill:
|
case leftSkill:
|
||||||
log.Println("Left Skill Action Pressed")
|
log.Println("Left Skill Action Pressed")
|
||||||
@ -1141,7 +1141,7 @@ func (g *GameControls) onClickActionable(item ActionableType) {
|
|||||||
g.miniPanel.Close()
|
g.miniPanel.Close()
|
||||||
g.escapeMenu.open()
|
g.escapeMenu.open()
|
||||||
default:
|
default:
|
||||||
log.Printf("Unrecognized ActionableType(%d) being clicked\n", item)
|
log.Printf("Unrecognized actionableType(%d) being clicked\n", item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ type Overlay struct {
|
|||||||
guiManager *d2gui.GuiManager
|
guiManager *d2gui.GuiManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewHelpOverlay creates a new HelpOverlay instance
|
||||||
func NewHelpOverlay(
|
func NewHelpOverlay(
|
||||||
asset *d2asset.AssetManager,
|
asset *d2asset.AssetManager,
|
||||||
renderer d2interface.Renderer,
|
renderer d2interface.Renderer,
|
||||||
@ -57,6 +58,7 @@ func NewHelpOverlay(
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Toggle the visibility state of the overlay
|
||||||
func (h *Overlay) Toggle() {
|
func (h *Overlay) Toggle() {
|
||||||
fmt.Print("Help overlay toggled\n")
|
fmt.Print("Help overlay toggled\n")
|
||||||
|
|
||||||
@ -85,10 +87,12 @@ func (h *Overlay) open() {
|
|||||||
h.guiManager.SetLayout(h.layout)
|
h.guiManager.SetLayout(h.layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsOpen returns whether or not the overlay is visible/open
|
||||||
func (h *Overlay) IsOpen() bool {
|
func (h *Overlay) IsOpen() bool {
|
||||||
return h.isOpen
|
return h.isOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsInRect checks if the given point is within the overlay layout rectangle
|
||||||
func (h *Overlay) IsInRect(px, py int) bool {
|
func (h *Overlay) IsInRect(px, py int) bool {
|
||||||
|
|
||||||
ww, hh := h.layout.GetSize()
|
ww, hh := h.layout.GetSize()
|
||||||
@ -101,8 +105,8 @@ func (h *Overlay) IsInRect(px, py int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the overlay graphical assets
|
||||||
func (h *Overlay) Load() {
|
func (h *Overlay) Load() {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
x = 0
|
x = 0
|
||||||
y = 0
|
y = 0
|
||||||
@ -485,6 +489,7 @@ func (h *Overlay) createCallout(c callout) {
|
|||||||
h.frames = append(h.frames, newDot)
|
h.frames = append(h.frames, newDot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render the overlay to the given surface
|
||||||
func (h *Overlay) Render(target d2interface.Surface) error {
|
func (h *Overlay) Render(target d2interface.Surface) error {
|
||||||
if !h.isOpen {
|
if !h.isOpen {
|
||||||
return nil
|
return nil
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package d2player
|
package d2player
|
||||||
|
|
||||||
type InputCallbackListener interface {
|
type inputCallbackListener interface {
|
||||||
OnPlayerMove(x, y float64)
|
OnPlayerMove(x, y float64)
|
||||||
OnPlayerCast(skillID int, x, y float64)
|
OnPlayerCast(skillID int, x, y float64)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
// for each row in inventory, we need to account for this padding
|
// for each row in inventory, we need to account for this padding
|
||||||
const cellPadding = 1
|
const cellPadding = 1
|
||||||
|
|
||||||
|
// InventoryItem is an interface for an items that can be placed in the inventory grid
|
||||||
type InventoryItem interface {
|
type InventoryItem interface {
|
||||||
InventoryGridSize() (width int, height int)
|
InventoryGridSize() (width int, height int)
|
||||||
GetItemCode() string
|
GetItemCode() string
|
||||||
@ -46,6 +47,7 @@ type ItemGrid struct {
|
|||||||
slotSize int
|
slotSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewItemGrid creates a new ItemGrid instance
|
||||||
func NewItemGrid(asset *d2asset.AssetManager, ui *d2ui.UIManager,
|
func NewItemGrid(asset *d2asset.AssetManager, ui *d2ui.UIManager,
|
||||||
record *d2records.InventoryRecord) *ItemGrid {
|
record *d2records.InventoryRecord) *ItemGrid {
|
||||||
grid := record.Grid
|
grid := record.Grid
|
||||||
@ -63,6 +65,7 @@ func NewItemGrid(asset *d2asset.AssetManager, ui *d2ui.UIManager,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SlotToScreen translates slot coordinates to screen coordinates
|
||||||
func (g *ItemGrid) SlotToScreen(slotX, slotY int) (screenX, screenY int) {
|
func (g *ItemGrid) SlotToScreen(slotX, slotY int) (screenX, screenY int) {
|
||||||
screenX = g.originX + slotX*g.slotSize
|
screenX = g.originX + slotX*g.slotSize
|
||||||
screenY = g.originY + slotY*g.slotSize
|
screenY = g.originY + slotY*g.slotSize
|
||||||
@ -70,6 +73,7 @@ func (g *ItemGrid) SlotToScreen(slotX, slotY int) (screenX, screenY int) {
|
|||||||
return screenX, screenY
|
return screenX, screenY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScreenToSlot translates screen coordinates to slot coordinates
|
||||||
func (g *ItemGrid) ScreenToSlot(screenX, screenY int) (slotX, slotY int) {
|
func (g *ItemGrid) ScreenToSlot(screenX, screenY int) (slotX, slotY int) {
|
||||||
slotX = (screenX - g.originX) / g.slotSize
|
slotX = (screenX - g.originX) / g.slotSize
|
||||||
slotY = (screenY - g.originY) / g.slotSize
|
slotY = (screenY - g.originY) / g.slotSize
|
||||||
@ -77,6 +81,7 @@ func (g *ItemGrid) ScreenToSlot(screenX, screenY int) (slotX, slotY int) {
|
|||||||
return slotX, slotY
|
return slotX, slotY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSlot returns the inventory item at a given slot (can return nil)
|
||||||
func (g *ItemGrid) GetSlot(x, y int) InventoryItem {
|
func (g *ItemGrid) GetSlot(x, y int) InventoryItem {
|
||||||
for _, item := range g.items {
|
for _, item := range g.items {
|
||||||
slotX, slotY := item.InventoryGridSlot()
|
slotX, slotY := item.InventoryGridSlot()
|
||||||
@ -90,6 +95,7 @@ func (g *ItemGrid) GetSlot(x, y int) InventoryItem {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ChangeEquippedSlot sets the item for an equipment slot
|
||||||
func (g *ItemGrid) ChangeEquippedSlot(slot d2enum.EquippedSlot, item InventoryItem) {
|
func (g *ItemGrid) ChangeEquippedSlot(slot d2enum.EquippedSlot, item InventoryItem) {
|
||||||
var curItem = g.equipmentSlots[slot]
|
var curItem = g.equipmentSlots[slot]
|
||||||
curItem.item = item
|
curItem.item = item
|
||||||
@ -186,6 +192,7 @@ func (g *ItemGrid) canFit(x, y int, item InventoryItem) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set an inventory item at the given grid coordinate
|
||||||
func (g *ItemGrid) Set(x, y int, item InventoryItem) error {
|
func (g *ItemGrid) Set(x, y int, item InventoryItem) error {
|
||||||
if !g.canFit(x, y, item) {
|
if !g.canFit(x, y, item) {
|
||||||
return fmt.Errorf("can not set item (%s) to position (%v, %v)", item.GetItemCode(), x, y)
|
return fmt.Errorf("can not set item (%s) to position (%v, %v)", item.GetItemCode(), x, y)
|
||||||
@ -232,6 +239,7 @@ func (g *ItemGrid) renderItem(item InventoryItem, target d2interface.Surface, x,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render the item grid to the given surface
|
||||||
func (g *ItemGrid) Render(target d2interface.Surface) {
|
func (g *ItemGrid) Render(target d2interface.Surface) {
|
||||||
g.renderInventoryItems(target)
|
g.renderInventoryItems(target)
|
||||||
g.renderEquippedItems(target)
|
g.renderEquippedItems(target)
|
||||||
|
@ -364,6 +364,7 @@ func (g *GameClient) handlePingPacket() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSinglePlayer returns a bool for whether the game is a single-player game
|
||||||
func (g *GameClient) IsSinglePlayer() bool {
|
func (g *GameClient) IsSinglePlayer() bool {
|
||||||
return g.connectionType == d2clientconnectiontype.Local
|
return g.connectionType == d2clientconnectiontype.Local
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ func (n NetPacketType) String() string {
|
|||||||
return strings[n]
|
return strings[n]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalPacket marshals the packet to a byte slice
|
||||||
func (n NetPacketType) MarshalPacket() []byte {
|
func (n NetPacketType) MarshalPacket() []byte {
|
||||||
p, err := json.Marshal(n)
|
p, err := json.Marshal(n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,6 +16,7 @@ type NetPacket struct {
|
|||||||
PacketData json.RawMessage `json:"packetData"`
|
PacketData json.RawMessage `json:"packetData"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InspectPacketType determines the packet type from the given data
|
||||||
func InspectPacketType(b []byte) d2netpackettype.NetPacketType {
|
func InspectPacketType(b []byte) d2netpackettype.NetPacketType {
|
||||||
var packet NetPacket
|
var packet NetPacket
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ func InspectPacketType(b []byte) d2netpackettype.NetPacketType {
|
|||||||
return packet.PacketType
|
return packet.PacketType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalNetPacket unmarshals the byte slice into a NetPacket struct
|
||||||
func UnmarshalNetPacket(packet []byte) (NetPacket, error) {
|
func UnmarshalNetPacket(packet []byte) (NetPacket, error) {
|
||||||
var p NetPacket
|
var p NetPacket
|
||||||
if err := json.Unmarshal(packet, &p); err != nil {
|
if err := json.Unmarshal(packet, &p); err != nil {
|
||||||
|
@ -50,6 +50,7 @@ func CreateAddPlayerPacket(id, name string, x, y int, heroType d2enum.Hero,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalAddPlayer unmarshals the packet data into an AddPlayerPacket struct
|
||||||
func UnmarshalAddPlayer(packet []byte) (AddPlayerPacket, error) {
|
func UnmarshalAddPlayer(packet []byte) (AddPlayerPacket, error) {
|
||||||
var p AddPlayerPacket
|
var p AddPlayerPacket
|
||||||
if err := json.Unmarshal(packet, &p); err != nil {
|
if err := json.Unmarshal(packet, &p); err != nil {
|
||||||
|
@ -33,6 +33,7 @@ func CreateGenerateMapPacket(regionType d2enum.RegionIdType) NetPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalGenerateMap unmarshals the given packet data into a GenerateMapPacket struct
|
||||||
func UnmarshalGenerateMap(packet []byte) (GenerateMapPacket, error) {
|
func UnmarshalGenerateMap(packet []byte) (GenerateMapPacket, error) {
|
||||||
var p GenerateMapPacket
|
var p GenerateMapPacket
|
||||||
if err := json.Unmarshal(packet, &p); err != nil {
|
if err := json.Unmarshal(packet, &p); err != nil {
|
||||||
|
@ -34,6 +34,7 @@ func CreateSpawnItemPacket(x, y int, codes ...string) NetPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalSpawnItem unmarshals the given data to a SpawnItemPacket struct
|
||||||
func UnmarshalSpawnItem(packet []byte) (SpawnItemPacket, error) {
|
func UnmarshalSpawnItem(packet []byte) (SpawnItemPacket, error) {
|
||||||
var p SpawnItemPacket
|
var p SpawnItemPacket
|
||||||
if err := json.Unmarshal(packet, &p); err != nil {
|
if err := json.Unmarshal(packet, &p); err != nil {
|
||||||
|
@ -40,6 +40,7 @@ func CreateMovePlayerPacket(playerID string, startX, startY, destX, destY float6
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalMovePlayer unmarshals the given data to a MovePlayerPacket struct
|
||||||
func UnmarshalMovePlayer(packet []byte) (MovePlayerPacket, error) {
|
func UnmarshalMovePlayer(packet []byte) (MovePlayerPacket, error) {
|
||||||
var p MovePlayerPacket
|
var p MovePlayerPacket
|
||||||
if err := json.Unmarshal(packet, &p); err != nil {
|
if err := json.Unmarshal(packet, &p); err != nil {
|
||||||
|
@ -41,6 +41,7 @@ func CreateCastPacket(entityID string, skillID int, targetX, targetY float64) Ne
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalCast unmarshals the given data to a CastPacket struct
|
||||||
func UnmarshalCast(packet []byte) (CastPacket, error) {
|
func UnmarshalCast(packet []byte) (CastPacket, error) {
|
||||||
var p CastPacket
|
var p CastPacket
|
||||||
if err := json.Unmarshal(packet, &p); err != nil {
|
if err := json.Unmarshal(packet, &p); err != nil {
|
||||||
|
@ -35,6 +35,8 @@ func CreatePlayerConnectionRequestPacket(id string, playerState *d2hero.HeroStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalPlayerConnectionRequest unmarshals the given data to a
|
||||||
|
// PlayerConnectionRequestPacket struct
|
||||||
func UnmarshalPlayerConnectionRequest(packet []byte) (PlayerConnectionRequestPacket, error) {
|
func UnmarshalPlayerConnectionRequest(packet []byte) (PlayerConnectionRequestPacket, error) {
|
||||||
var resp PlayerConnectionRequestPacket
|
var resp PlayerConnectionRequestPacket
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ func CreatePlayerDisconnectRequestPacket(id string) NetPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalPlayerDisconnectionRequest unmarshals the given data to a
|
||||||
|
// PlayerDisconnectRequestPacket struct
|
||||||
func UnmarshalPlayerDisconnectionRequest(packet []byte) (PlayerDisconnectRequestPacket, error) {
|
func UnmarshalPlayerDisconnectionRequest(packet []byte) (PlayerDisconnectRequestPacket, error) {
|
||||||
var resp PlayerDisconnectRequestPacket
|
var resp PlayerDisconnectRequestPacket
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ func CreatePongPacket(id string) NetPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalPong unmarshals the given data to a PongPacket struct
|
||||||
func UnmarshalPong(packet []byte) (PongPacket, error) {
|
func UnmarshalPong(packet []byte) (PongPacket, error) {
|
||||||
var resp PongPacket
|
var resp PongPacket
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ func CreateServerClosedPacket() NetPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalServerClosed unmarshals the given data to a ServerClosedPacket struct
|
||||||
func UnmarshalServerClosed(packet []byte) (ServerClosedPacket, error) {
|
func UnmarshalServerClosed(packet []byte) (ServerClosedPacket, error) {
|
||||||
var resp ServerClosedPacket
|
var resp ServerClosedPacket
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ func CreateUpdateServerInfoPacket(seed int64, playerID string) NetPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalUpdateServerInfo unmarshals the data to a UpdateServerInfoPacket struct
|
||||||
func UnmarshalUpdateServerInfo(packet []byte) (UpdateServerInfoPacket, error) {
|
func UnmarshalUpdateServerInfo(packet []byte) (UpdateServerInfoPacket, error) {
|
||||||
var resp UpdateServerInfoPacket
|
var resp UpdateServerInfoPacket
|
||||||
|
|
||||||
|
@ -11,12 +11,14 @@ import (
|
|||||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket"
|
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TCPClientConnection represents a client connection over TCP
|
||||||
type TCPClientConnection struct {
|
type TCPClientConnection struct {
|
||||||
id string
|
id string
|
||||||
tcpConnection net.Conn
|
tcpConnection net.Conn
|
||||||
playerState *d2hero.HeroState
|
playerState *d2hero.HeroState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateTCPClientConnection creates a new tcp client connection instance
|
||||||
func CreateTCPClientConnection(tcpConnection net.Conn, id string) *TCPClientConnection {
|
func CreateTCPClientConnection(tcpConnection net.Conn, id string) *TCPClientConnection {
|
||||||
return &TCPClientConnection{
|
return &TCPClientConnection{
|
||||||
tcpConnection: tcpConnection,
|
tcpConnection: tcpConnection,
|
||||||
@ -24,10 +26,12 @@ func CreateTCPClientConnection(tcpConnection net.Conn, id string) *TCPClientConn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUniqueID returns the unique ID for the tcp client connection
|
||||||
func (t TCPClientConnection) GetUniqueID() string {
|
func (t TCPClientConnection) GetUniqueID() string {
|
||||||
return t.id
|
return t.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SendPacketToClient marshals and sends (writes) NetPackets
|
||||||
func (t *TCPClientConnection) SendPacketToClient(p d2netpacket.NetPacket) error {
|
func (t *TCPClientConnection) SendPacketToClient(p d2netpacket.NetPacket) error {
|
||||||
packet, err := json.Marshal(p)
|
packet, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -42,10 +46,12 @@ func (t *TCPClientConnection) SendPacketToClient(p d2netpacket.NetPacket) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPlayerState sets the game client player state
|
||||||
func (t *TCPClientConnection) SetPlayerState(playerState *d2hero.HeroState) {
|
func (t *TCPClientConnection) SetPlayerState(playerState *d2hero.HeroState) {
|
||||||
t.playerState = playerState
|
t.playerState = playerState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPlayerState gets the game client player state
|
||||||
func (t *TCPClientConnection) GetPlayerState() *d2hero.HeroState {
|
func (t *TCPClientConnection) GetPlayerState() *d2hero.HeroState {
|
||||||
return t.playerState
|
return t.playerState
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user