mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-10 10:36:42 -05:00
lint fixes for the d2common package (#558)
This commit is contained in:
parent
db5e844aac
commit
d1f499fb79
@ -1,10 +1,12 @@
|
|||||||
package d2common
|
package d2common
|
||||||
|
|
||||||
|
// Point represents a point
|
||||||
type Point struct {
|
type Point struct {
|
||||||
X int
|
X int
|
||||||
Y int
|
Y int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pointf represents a point with float coordinates
|
||||||
type Pointf struct {
|
type Pointf struct {
|
||||||
X float64
|
X float64
|
||||||
Y float64
|
Y float64
|
||||||
|
@ -18,6 +18,7 @@ func CreateBitStream(newData []byte) *BitStream {
|
|||||||
current: 0,
|
current: 0,
|
||||||
bitCount: 0,
|
bitCount: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,11 +27,14 @@ func (v *BitStream) ReadBits(bitCount int) int {
|
|||||||
if bitCount > 16 {
|
if bitCount > 16 {
|
||||||
log.Panic("Maximum BitCount is 16")
|
log.Panic("Maximum BitCount is 16")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !v.EnsureBits(bitCount) {
|
if !v.EnsureBits(bitCount) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
result := v.current & (0xffff >> uint(16-bitCount))
|
result := v.current & (0xffff >> uint(16-bitCount))
|
||||||
v.WasteBits(bitCount)
|
v.WasteBits(bitCount)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +43,7 @@ func (v *BitStream) PeekByte() int {
|
|||||||
if !v.EnsureBits(8) {
|
if !v.EnsureBits(8) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.current & 0xff
|
return v.current & 0xff
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,19 +52,22 @@ func (v *BitStream) EnsureBits(bitCount int) bool {
|
|||||||
if bitCount <= v.bitCount {
|
if bitCount <= v.bitCount {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.dataPosition >= len(v.data) {
|
if v.dataPosition >= len(v.data) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
nextValue := v.data[v.dataPosition]
|
nextValue := v.data[v.dataPosition]
|
||||||
v.dataPosition++
|
v.dataPosition++
|
||||||
v.current |= int(nextValue) << uint(v.bitCount)
|
v.current |= int(nextValue) << uint(v.bitCount)
|
||||||
v.bitCount += 8
|
v.bitCount += 8
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// WasteBits dry-reads the specified number of bits
|
// WasteBits dry-reads the specified number of bits
|
||||||
func (v *BitStream) WasteBits(bitCount int) {
|
func (v *BitStream) WasteBits(bitCount int) {
|
||||||
//noinspection GoRedundantConversion
|
// noinspection GoRedundantConversion
|
||||||
v.current >>= uint(bitCount)
|
v.current >>= uint(bitCount)
|
||||||
v.bitCount -= bitCount
|
v.bitCount -= bitCount
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,13 @@ func TestBitStreamBits(t *testing.T) {
|
|||||||
data := []byte{0xAA}
|
data := []byte{0xAA}
|
||||||
bitStream := CreateBitStream(data)
|
bitStream := CreateBitStream(data)
|
||||||
shouldBeOne := 0
|
shouldBeOne := 0
|
||||||
|
|
||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
bit := bitStream.ReadBits(1)
|
bit := bitStream.ReadBits(1)
|
||||||
if bit != shouldBeOne {
|
if bit != shouldBeOne {
|
||||||
t.Fatalf("Expected %d but got %d on iteration %d", shouldBeOne, bit, i)
|
t.Fatalf("Expected %d but got %d on iteration %d", shouldBeOne, bit, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if shouldBeOne == 1 {
|
if shouldBeOne == 1 {
|
||||||
shouldBeOne = 0
|
shouldBeOne = 0
|
||||||
} else {
|
} else {
|
||||||
@ -24,6 +26,7 @@ func TestBitStreamBits(t *testing.T) {
|
|||||||
func TestBitStreamBytes(t *testing.T) {
|
func TestBitStreamBytes(t *testing.T) {
|
||||||
data := []byte{0xAA, 0xBB, 0xCC, 0xDD, 0x12, 0x34, 0x56, 0x78}
|
data := []byte{0xAA, 0xBB, 0xCC, 0xDD, 0x12, 0x34, 0x56, 0x78}
|
||||||
bitStream := CreateBitStream(data)
|
bitStream := CreateBitStream(data)
|
||||||
|
|
||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
b := byte(bitStream.ReadBits(8))
|
b := byte(bitStream.ReadBits(8))
|
||||||
if b != data[i] {
|
if b != data[i] {
|
||||||
|
@ -2,9 +2,10 @@ package d2common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||||
)
|
)
|
||||||
|
|
||||||
type cacheNode struct {
|
type cacheNode struct {
|
||||||
@ -109,6 +110,7 @@ func (c *Cache) Retrieve(key string) (interface{}, bool) {
|
|||||||
if node.next != nil {
|
if node.next != nil {
|
||||||
node.next.prev = node.prev
|
node.next.prev = node.prev
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.prev != nil {
|
if node.prev != nil {
|
||||||
node.prev.next = node.next
|
node.prev.next = node.next
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package d2common
|
package d2common
|
||||||
|
|
||||||
// a calcstring is a type of string often used in datafiles to specify
|
// CalcString is a type of string often used in datafiles to specify
|
||||||
// a value that is calculated dynamically based on the stats of the relevant
|
// a value that is calculated dynamically based on the stats of the relevant
|
||||||
// source, for instance a missile might have a movement speed of lvl*2
|
// source, for instance a missile might have a movement speed of lvl*2
|
||||||
|
|
||||||
type CalcString string
|
type CalcString string
|
||||||
|
|
||||||
// todo: the logic for parsing these should exist here
|
// todo: the logic for parsing these should exist here
|
||||||
|
@ -27,7 +27,7 @@ func LoadAnimationData(rawData []byte) {
|
|||||||
AnimationData = make(map[string][]*AnimationDataRecord)
|
AnimationData = make(map[string][]*AnimationDataRecord)
|
||||||
streamReader := d2common.CreateStreamReader(rawData)
|
streamReader := d2common.CreateStreamReader(rawData)
|
||||||
|
|
||||||
for !streamReader.Eof() {
|
for !streamReader.EOF() {
|
||||||
dataCount := int(streamReader.GetInt32())
|
dataCount := int(streamReader.GetInt32())
|
||||||
for i := 0; i < dataCount; i++ {
|
for i := 0; i < dataCount; i++ {
|
||||||
cofNameBytes := streamReader.ReadBytes(8)
|
cofNameBytes := streamReader.ReadBytes(8)
|
||||||
|
@ -41,10 +41,11 @@ func LoadDataDictionary(buf []byte) *DataDictionary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Next reads the next row, skips Expansion lines or
|
// Next reads the next row, skips Expansion lines or
|
||||||
// returns false when the end of a file is reached or an error occured
|
// returns false when the end of a file is reached or an error occurred
|
||||||
func (d *DataDictionary) Next() bool {
|
func (d *DataDictionary) Next() bool {
|
||||||
var err error
|
var err error
|
||||||
d.record, err = d.r.Read()
|
d.record, err = d.r.Read()
|
||||||
|
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return false
|
return false
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@ -55,6 +56,7 @@ func (d *DataDictionary) Next() bool {
|
|||||||
if d.record[0] == "Expansion" {
|
if d.record[0] == "Expansion" {
|
||||||
return d.Next()
|
return d.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +71,7 @@ func (d *DataDictionary) Number(field string) int {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,5 +87,6 @@ func (d *DataDictionary) Bool(field string) bool {
|
|||||||
if n > 1 {
|
if n > 1 {
|
||||||
log.Panic("Bool on non-bool field")
|
log.Panic("Bool on non-bool field")
|
||||||
}
|
}
|
||||||
|
|
||||||
return n == 1
|
return n == 1
|
||||||
}
|
}
|
||||||
|
@ -4,17 +4,21 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MinInt returns the minimum of the given values
|
||||||
func MinInt(a, b int) int {
|
func MinInt(a, b int) int {
|
||||||
if a < b {
|
if a < b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaxInt returns the maximum of the given values
|
||||||
func MaxInt(a, b int) int {
|
func MaxInt(a, b int) int {
|
||||||
if a > b {
|
if a > b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +27,7 @@ func Min(a, b uint32) uint32 {
|
|||||||
if a < b {
|
if a < b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +36,7 @@ func Max(a, b uint32) uint32 {
|
|||||||
if a > b {
|
if a > b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,13 +45,16 @@ func MaxInt32(a, b int32) int32 {
|
|||||||
if a > b {
|
if a > b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AbsInt32 returns the absolute of the given int32
|
||||||
func AbsInt32(a int32) int32 {
|
func AbsInt32(a int32) int32 {
|
||||||
if a < 0 {
|
if a < 0 {
|
||||||
return -a
|
return -a
|
||||||
}
|
}
|
||||||
|
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +63,7 @@ func MinInt32(a, b int32) int32 {
|
|||||||
if a < b {
|
if a < b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,12 +80,15 @@ func GetAngleBetween(p1X, p1Y, p2X, p2Y float64) int {
|
|||||||
|
|
||||||
result := math.Atan2(deltaY, deltaX) * (180 / math.Pi)
|
result := math.Atan2(deltaY, deltaX) * (180 / math.Pi)
|
||||||
iResult := int(result)
|
iResult := int(result)
|
||||||
|
|
||||||
for iResult < 0 {
|
for iResult < 0 {
|
||||||
iResult += 360
|
iResult += 360
|
||||||
}
|
}
|
||||||
|
|
||||||
for iResult >= 360 {
|
for iResult >= 360 {
|
||||||
iResult -= 360
|
iResult -= 360
|
||||||
}
|
}
|
||||||
|
|
||||||
return iResult
|
return iResult
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,17 +105,18 @@ func AlmostEqual(a, b, threshold float64) bool {
|
|||||||
return math.Abs(a-b) <= threshold
|
return math.Abs(a-b) <= threshold
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the new adjusted value, as well as any remaining amount after the max
|
// AdjustWithRemainder returns the new adjusted value, as well as any remaining amount after the max
|
||||||
func AdjustWithRemainder(sourceValue, adjustment, targetvalue float64) (newValue, remainder float64) {
|
func AdjustWithRemainder(sourceValue, adjustment, targetvalue float64) (newValue, remainder float64) {
|
||||||
if adjustment == 0 || math.Abs(adjustment) < 0.000001 {
|
if adjustment == 0 || math.Abs(adjustment) < 0.000001 {
|
||||||
return sourceValue, 0
|
return sourceValue, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
adjustNegative := adjustment < 0.0
|
adjustNegative := adjustment < 0.0
|
||||||
maxNegative := targetvalue-sourceValue < 0.0
|
maxNegative := targetvalue-sourceValue < 0.0
|
||||||
|
|
||||||
if adjustNegative != maxNegative {
|
if adjustNegative != maxNegative {
|
||||||
// FIXME: This shouldn't happen but it happens all the time..
|
// FIXME: This shouldn't happen but it happens all the time..
|
||||||
return sourceValue, 0
|
return sourceValue, 0
|
||||||
//panic("Cannot move towards the opposite direction...")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finalValue := sourceValue + adjustment
|
finalValue := sourceValue + adjustment
|
||||||
@ -111,11 +125,13 @@ func AdjustWithRemainder(sourceValue, adjustment, targetvalue float64) (newValue
|
|||||||
diff := finalValue - targetvalue
|
diff := finalValue - targetvalue
|
||||||
return targetvalue, diff
|
return targetvalue, diff
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalValue, 0
|
return finalValue, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if finalValue < targetvalue {
|
if finalValue < targetvalue {
|
||||||
return targetvalue, finalValue - targetvalue
|
return targetvalue, finalValue - targetvalue
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalValue, 0
|
return finalValue, 0
|
||||||
}
|
}
|
||||||
|
@ -2,51 +2,56 @@ package d2common
|
|||||||
|
|
||||||
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
|
|
||||||
|
// MusicDef stores the music definitions of a region
|
||||||
type MusicDef struct {
|
type MusicDef struct {
|
||||||
Region d2enum.RegionIdType
|
Region d2enum.RegionIdType
|
||||||
InTown bool
|
InTown bool
|
||||||
MusicFile string
|
MusicFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
var musicDefs = [...]MusicDef{
|
func getMusicDefs() []MusicDef {
|
||||||
{d2enum.RegionAct1Town, false, "/data/global/music/Act1/town1.wav"},
|
return []MusicDef{
|
||||||
{d2enum.RegionAct1Wilderness, false, "/data/global/music/Act1/wild.wav"},
|
{d2enum.RegionAct1Town, false, "/data/global/music/Act1/town1.wav"},
|
||||||
{d2enum.RegionAct1Cave, false, "/data/global/music/Act1/caves.wav"},
|
{d2enum.RegionAct1Wilderness, false, "/data/global/music/Act1/wild.wav"},
|
||||||
{d2enum.RegionAct1Crypt, false, "/data/global/music/Act1/crypt.wav"},
|
{d2enum.RegionAct1Cave, false, "/data/global/music/Act1/caves.wav"},
|
||||||
{d2enum.RegionAct1Monestary, false, "/data/global/music/Act1/monastery.wav"},
|
{d2enum.RegionAct1Crypt, false, "/data/global/music/Act1/crypt.wav"},
|
||||||
{d2enum.RegionAct1Courtyard, false, "/data/global/music/Act1/wild.wav"}, // ?
|
{d2enum.RegionAct1Monestary, false, "/data/global/music/Act1/monastery.wav"},
|
||||||
{d2enum.RegionAct1Barracks, false, "/data/global/music/Act1/wild.wav"}, // ?
|
{d2enum.RegionAct1Courtyard, false, "/data/global/music/Act1/wild.wav"}, // ?
|
||||||
{d2enum.RegionAct1Jail, false, "/data/global/music/Act1/wild.wav"}, // ?
|
{d2enum.RegionAct1Barracks, false, "/data/global/music/Act1/wild.wav"}, // ?
|
||||||
{d2enum.RegionAct1Cathedral, false, "/data/global/music/Act1/monastery.wav"}, // ?
|
{d2enum.RegionAct1Jail, false, "/data/global/music/Act1/wild.wav"}, // ?
|
||||||
{d2enum.RegionAct1Catacombs, false, "/data/global/music/Act1/crypt.wav"}, // ?
|
{d2enum.RegionAct1Cathedral, false, "/data/global/music/Act1/monastery.wav"}, // ?
|
||||||
{d2enum.RegionAct1Tristram, false, "/data/global/music/Act1/tristram.wav"}, // ?
|
{d2enum.RegionAct1Catacombs, false, "/data/global/music/Act1/crypt.wav"}, // ?
|
||||||
{d2enum.RegionAct2Town, false, "/data/global/music/Act2/town2.wav"},
|
{d2enum.RegionAct1Tristram, false, "/data/global/music/Act1/tristram.wav"}, // ?
|
||||||
{d2enum.RegionAct2Sewer, false, "/data/global/music/Act2/sewer.wav"},
|
{d2enum.RegionAct2Town, false, "/data/global/music/Act2/town2.wav"},
|
||||||
{d2enum.RegionAct2Harem, false, "/data/global/music/Act2/harem.wav"},
|
{d2enum.RegionAct2Sewer, false, "/data/global/music/Act2/sewer.wav"},
|
||||||
{d2enum.RegionAct2Basement, false, "/data/global/music/Act2/lair.wav"}, // ?
|
{d2enum.RegionAct2Harem, false, "/data/global/music/Act2/harem.wav"},
|
||||||
{d2enum.RegionAct2Desert, false, "/data/global/music/Act2/desrt.wav"},
|
{d2enum.RegionAct2Basement, false, "/data/global/music/Act2/lair.wav"}, // ?
|
||||||
{d2enum.RegionAct2Tomb, false, "/data/global/music/Act2/tombs.wav"},
|
{d2enum.RegionAct2Desert, false, "/data/global/music/Act2/desrt.wav"},
|
||||||
{d2enum.RegionAct2Lair, false, "/data/global/music/Act2/lair.wav"},
|
{d2enum.RegionAct2Tomb, false, "/data/global/music/Act2/tombs.wav"},
|
||||||
{d2enum.RegionAct2Arcane, false, "/data/global/music/Act2/sanctuary.wav"}, // ?
|
{d2enum.RegionAct2Lair, false, "/data/global/music/Act2/lair.wav"},
|
||||||
{d2enum.RegionAct3Town, false, "/data/global/music/Act3/town3.wav"},
|
{d2enum.RegionAct2Arcane, false, "/data/global/music/Act2/sanctuary.wav"}, // ?
|
||||||
{d2enum.RegionAct3Jungle, false, "/data/global/music/Act3/jungle.wav"},
|
{d2enum.RegionAct3Town, false, "/data/global/music/Act3/town3.wav"},
|
||||||
{d2enum.RegionAct3Kurast, false, "/data/global/music/Act3/kurast.wav"},
|
{d2enum.RegionAct3Jungle, false, "/data/global/music/Act3/jungle.wav"},
|
||||||
{d2enum.RegionAct3Spider, false, "/data/global/music/Act3/spider.wav"},
|
{d2enum.RegionAct3Kurast, false, "/data/global/music/Act3/kurast.wav"},
|
||||||
{d2enum.RegionAct3Dungeon, false, "/data/global/music/Act3/kurastsewer.wav"}, // ?
|
{d2enum.RegionAct3Spider, false, "/data/global/music/Act3/spider.wav"},
|
||||||
{d2enum.RegionAct3Sewer, false, "/data/global/music/Act3/kurastsewer.wav"},
|
{d2enum.RegionAct3Dungeon, false, "/data/global/music/Act3/kurastsewer.wav"}, // ?
|
||||||
{d2enum.RegionAct4Town, false, "/data/global/music/Act4/town4.wav"},
|
{d2enum.RegionAct3Sewer, false, "/data/global/music/Act3/kurastsewer.wav"},
|
||||||
{d2enum.RegionAct4Mesa, false, "/data/global/music/Act4/mesa.wav"},
|
{d2enum.RegionAct4Town, false, "/data/global/music/Act4/town4.wav"},
|
||||||
{d2enum.RegionAct4Lava, false, "/data/global/music/Act4/diablo.wav"}, // ?
|
{d2enum.RegionAct4Mesa, false, "/data/global/music/Act4/mesa.wav"},
|
||||||
{d2enum.RegonAct5Town, false, "/data/global/music/Act5/xtown.wav"},
|
{d2enum.RegionAct4Lava, false, "/data/global/music/Act4/diablo.wav"}, // ?
|
||||||
{d2enum.RegionAct5Siege, false, "/data/global/music/Act5/siege.wav"},
|
{d2enum.RegonAct5Town, false, "/data/global/music/Act5/xtown.wav"},
|
||||||
{d2enum.RegionAct5Barricade, false, "/data/global/music/Act5/shenkmusic.wav"}, // ?
|
{d2enum.RegionAct5Siege, false, "/data/global/music/Act5/siege.wav"},
|
||||||
{d2enum.RegionAct5Temple, false, "/data/global/music/Act5/xtemple.wav"},
|
{d2enum.RegionAct5Barricade, false, "/data/global/music/Act5/shenkmusic.wav"}, // ?
|
||||||
{d2enum.RegionAct5IceCaves, false, "/data/global/music/Act5/icecaves.wav"},
|
{d2enum.RegionAct5Temple, false, "/data/global/music/Act5/xtemple.wav"},
|
||||||
{d2enum.RegionAct5Baal, false, "/data/global/music/Act5/baal.wav"},
|
{d2enum.RegionAct5IceCaves, false, "/data/global/music/Act5/icecaves.wav"},
|
||||||
{d2enum.RegionAct5Lava, false, "/data/global/music/Act5/nihlathakmusic.wav"}, // ?
|
{d2enum.RegionAct5Baal, false, "/data/global/music/Act5/baal.wav"},
|
||||||
|
{d2enum.RegionAct5Lava, false, "/data/global/music/Act5/nihlathakmusic.wav"}, // ?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMusicDef returns the MusicDef of the given region
|
||||||
func GetMusicDef(regionType d2enum.RegionIdType) *MusicDef {
|
func GetMusicDef(regionType d2enum.RegionIdType) *MusicDef {
|
||||||
|
musicDefs := getMusicDefs()
|
||||||
for idx := range musicDefs {
|
for idx := range musicDefs {
|
||||||
if musicDefs[idx].Region != regionType {
|
if musicDefs[idx].Region != regionType {
|
||||||
continue
|
continue
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package d2common
|
package d2common
|
||||||
|
|
||||||
|
// Path represents a path
|
||||||
type Path struct {
|
type Path struct {
|
||||||
X int
|
X int
|
||||||
Y int
|
Y int
|
||||||
|
@ -2,35 +2,44 @@ package d2common
|
|||||||
|
|
||||||
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2astar"
|
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2astar"
|
||||||
|
|
||||||
|
// PathTile represents a node in path finding
|
||||||
type PathTile struct {
|
type PathTile struct {
|
||||||
Walkable bool
|
Walkable bool
|
||||||
Up, Down, Left, Right, UpLeft, UpRight, DownLeft, DownRight *PathTile
|
Up, Down, Left, Right, UpLeft, UpRight, DownLeft, DownRight *PathTile
|
||||||
X, Y float64
|
X, Y float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PathNeighbors returns the direct neighboring nodes of this node which can be pathed to
|
||||||
func (t *PathTile) PathNeighbors() []d2astar.Pather {
|
func (t *PathTile) PathNeighbors() []d2astar.Pather {
|
||||||
result := make([]d2astar.Pather, 0, 8)
|
result := make([]d2astar.Pather, 0, 8)
|
||||||
if t.Up != nil {
|
if t.Up != nil {
|
||||||
result = append(result, t.Up)
|
result = append(result, t.Up)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Right != nil {
|
if t.Right != nil {
|
||||||
result = append(result, t.Right)
|
result = append(result, t.Right)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Down != nil {
|
if t.Down != nil {
|
||||||
result = append(result, t.Down)
|
result = append(result, t.Down)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Left != nil {
|
if t.Left != nil {
|
||||||
result = append(result, t.Left)
|
result = append(result, t.Left)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.UpLeft != nil {
|
if t.UpLeft != nil {
|
||||||
result = append(result, t.UpLeft)
|
result = append(result, t.UpLeft)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.UpRight != nil {
|
if t.UpRight != nil {
|
||||||
result = append(result, t.UpRight)
|
result = append(result, t.UpRight)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.DownLeft != nil {
|
if t.DownLeft != nil {
|
||||||
result = append(result, t.DownLeft)
|
result = append(result, t.DownLeft)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.DownRight != nil {
|
if t.DownRight != nil {
|
||||||
result = append(result, t.DownRight)
|
result = append(result, t.DownRight)
|
||||||
}
|
}
|
||||||
@ -38,20 +47,26 @@ func (t *PathTile) PathNeighbors() []d2astar.Pather {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PathNeighborCost calculates the exact movement cost to neighbor nodes
|
||||||
func (t *PathTile) PathNeighborCost(to d2astar.Pather) float64 {
|
func (t *PathTile) PathNeighborCost(to d2astar.Pather) float64 {
|
||||||
return 1 // No cost specifics currently...
|
return 1 // No cost specifics currently...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PathEstimatedCost is a heuristic method for estimating movement costs between non-adjacent nodes
|
||||||
func (t *PathTile) PathEstimatedCost(to d2astar.Pather) float64 {
|
func (t *PathTile) PathEstimatedCost(to d2astar.Pather) float64 {
|
||||||
toT := to.(*PathTile)
|
toT := to.(*PathTile)
|
||||||
absX := toT.X - t.X
|
absX := toT.X - t.X
|
||||||
|
|
||||||
if absX < 0 {
|
if absX < 0 {
|
||||||
absX = -absX
|
absX = -absX
|
||||||
}
|
}
|
||||||
|
|
||||||
absY := toT.Y - t.Y
|
absY := toT.Y - t.Y
|
||||||
|
|
||||||
if absY < 0 {
|
if absY < 0 {
|
||||||
absY = -absY
|
absY = -absY
|
||||||
}
|
}
|
||||||
|
|
||||||
r := absX + absY
|
r := absX + absY
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package d2common
|
package d2common
|
||||||
|
|
||||||
|
// Rectangle represents a rectangle
|
||||||
type Rectangle struct {
|
type Rectangle struct {
|
||||||
Left int
|
Left int
|
||||||
Top int
|
Top int
|
||||||
@ -7,14 +8,17 @@ type Rectangle struct {
|
|||||||
Height int
|
Height int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bottom returns y of the bottom point of the rectangle
|
||||||
func (v *Rectangle) Bottom() int {
|
func (v *Rectangle) Bottom() int {
|
||||||
return v.Top + v.Height
|
return v.Top + v.Height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Right returns x of the right point of the rectangle
|
||||||
func (v *Rectangle) Right() int {
|
func (v *Rectangle) Right() int {
|
||||||
return v.Left + v.Width
|
return v.Left + v.Width
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsInRect returns if the given position is in the rectangle or not
|
||||||
func (v *Rectangle) IsInRect(x, y int) bool {
|
func (v *Rectangle) IsInRect(x, y int) bool {
|
||||||
return x >= v.Left && x < v.Left+v.Width && y >= v.Top && y < v.Top+v.Height
|
return x >= v.Left && x < v.Left+v.Width && y >= v.Top && y < v.Top+v.Height
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package d2common
|
package d2common
|
||||||
|
|
||||||
|
// Size represents a size
|
||||||
type Size struct {
|
type Size struct {
|
||||||
Width, Height int
|
Width, Height int
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ func CreateStreamReader(source []byte) *StreamReader {
|
|||||||
data: source,
|
data: source,
|
||||||
position: 0,
|
position: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ func (v *StreamReader) GetSize() uint64 {
|
|||||||
func (v *StreamReader) GetByte() byte {
|
func (v *StreamReader) GetByte() byte {
|
||||||
result := v.data[v.position]
|
result := v.data[v.position]
|
||||||
v.position++
|
v.position++
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +43,7 @@ func (v *StreamReader) GetUInt16() uint16 {
|
|||||||
result := uint16(v.data[v.position])
|
result := uint16(v.data[v.position])
|
||||||
result += uint16(v.data[v.position+1]) << 8
|
result += uint16(v.data[v.position+1]) << 8
|
||||||
v.position += 2
|
v.position += 2
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,24 +51,34 @@ func (v *StreamReader) GetUInt16() uint16 {
|
|||||||
func (v *StreamReader) GetInt16() int16 {
|
func (v *StreamReader) GetInt16() int16 {
|
||||||
result := (int16(v.data[v.position+1]) << uint(8)) + int16(v.data[v.position])
|
result := (int16(v.data[v.position+1]) << uint(8)) + int16(v.data[v.position])
|
||||||
v.position += 2
|
v.position += 2
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPosition sets the stream position with the given position
|
||||||
func (v *StreamReader) SetPosition(newPosition uint64) {
|
func (v *StreamReader) SetPosition(newPosition uint64) {
|
||||||
v.position = newPosition
|
v.position = newPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUInt32 returns a uint32 dword from the stream
|
// GetUInt32 returns a uint32 dword from the stream
|
||||||
func (v *StreamReader) GetUInt32() uint32 {
|
func (v *StreamReader) GetUInt32() uint32 {
|
||||||
result := (uint32(v.data[v.position+3]) << uint(24)) + (uint32(v.data[v.position+2]) << uint(16)) + (uint32(v.data[v.position+1]) << uint(8)) + uint32(v.data[v.position])
|
result := (uint32(v.data[v.position+3]) << uint(24)) +
|
||||||
|
(uint32(v.data[v.position+2]) << uint(16)) +
|
||||||
|
(uint32(v.data[v.position+1]) << uint(8)) +
|
||||||
|
uint32(v.data[v.position])
|
||||||
v.position += 4
|
v.position += 4
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInt32 returns an int32 dword from the stream
|
// GetInt32 returns an int32 dword from the stream
|
||||||
func (v *StreamReader) GetInt32() int32 {
|
func (v *StreamReader) GetInt32() int32 {
|
||||||
result := (int32(v.data[v.position+3]) << uint(24)) + (int32(v.data[v.position+2]) << uint(16)) + (int32(v.data[v.position+1]) << uint(8)) + int32(v.data[v.position])
|
result := (int32(v.data[v.position+3]) << uint(24)) +
|
||||||
|
(int32(v.data[v.position+2]) << uint(16)) +
|
||||||
|
(int32(v.data[v.position+1]) << uint(8)) +
|
||||||
|
int32(v.data[v.position])
|
||||||
v.position += 4
|
v.position += 4
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,21 +93,13 @@ func (v *StreamReader) GetUint64() uint64 {
|
|||||||
(uint64(v.data[v.position+1]) << uint(8)) +
|
(uint64(v.data[v.position+1]) << uint(8)) +
|
||||||
uint64(v.data[v.position])
|
uint64(v.data[v.position])
|
||||||
v.position += 8
|
v.position += 8
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInt64 returns a uint64 qword from the stream
|
// GetInt64 returns a uint64 qword from the stream
|
||||||
func (v *StreamReader) GetInt64() int64 {
|
func (v *StreamReader) GetInt64() int64 {
|
||||||
result := (uint64(v.data[v.position+7]) << uint(56)) +
|
return int64(v.GetUint64())
|
||||||
(uint64(v.data[v.position+6]) << uint(48)) +
|
|
||||||
(uint64(v.data[v.position+5]) << uint(40)) +
|
|
||||||
(uint64(v.data[v.position+4]) << uint(32)) +
|
|
||||||
(uint64(v.data[v.position+3]) << uint(24)) +
|
|
||||||
(uint64(v.data[v.position+2]) << uint(16)) +
|
|
||||||
(uint64(v.data[v.position+1]) << uint(8)) +
|
|
||||||
uint64(v.data[v.position])
|
|
||||||
v.position += 8
|
|
||||||
return int64(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadByte implements io.ByteReader
|
// ReadByte implements io.ByteReader
|
||||||
@ -106,9 +111,11 @@ func (v *StreamReader) ReadByte() (byte, error) {
|
|||||||
func (v *StreamReader) ReadBytes(count int) []byte {
|
func (v *StreamReader) ReadBytes(count int) []byte {
|
||||||
result := v.data[v.position : v.position+uint64(count)]
|
result := v.data[v.position : v.position+uint64(count)]
|
||||||
v.position += uint64(count)
|
v.position += uint64(count)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SkipBytes moves the stream position forward by the given amount
|
||||||
func (v *StreamReader) SkipBytes(count int) {
|
func (v *StreamReader) SkipBytes(count int) {
|
||||||
v.position += uint64(count)
|
v.position += uint64(count)
|
||||||
}
|
}
|
||||||
@ -116,17 +123,21 @@ func (v *StreamReader) SkipBytes(count int) {
|
|||||||
// Read implements io.Reader
|
// Read implements io.Reader
|
||||||
func (v *StreamReader) Read(p []byte) (n int, err error) {
|
func (v *StreamReader) Read(p []byte) (n int, err error) {
|
||||||
streamLength := v.GetSize()
|
streamLength := v.GetSize()
|
||||||
|
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
if v.GetPosition() >= streamLength {
|
if v.GetPosition() >= streamLength {
|
||||||
return i, io.EOF
|
return i, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
if i >= len(p) {
|
if i >= len(p) {
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p[i] = v.GetByte()
|
p[i] = v.GetByte()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *StreamReader) Eof() bool {
|
// EOF returns if the stream position is reached to the end of the data, or not
|
||||||
|
func (v *StreamReader) EOF() bool {
|
||||||
return v.position >= uint64(len(v.data))
|
return v.position >= uint64(len(v.data))
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,21 @@ import (
|
|||||||
func TestStreamReaderByte(t *testing.T) {
|
func TestStreamReaderByte(t *testing.T) {
|
||||||
data := []byte{0x78, 0x56, 0x34, 0x12}
|
data := []byte{0x78, 0x56, 0x34, 0x12}
|
||||||
sr := CreateStreamReader(data)
|
sr := CreateStreamReader(data)
|
||||||
|
|
||||||
if sr.GetPosition() != 0 {
|
if sr.GetPosition() != 0 {
|
||||||
t.Fatal("StreamReader.GetPosition() did not start at 0")
|
t.Fatal("StreamReader.GetPosition() did not start at 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ss := sr.GetSize(); ss != 4 {
|
if ss := sr.GetSize(); ss != 4 {
|
||||||
t.Fatalf("StreamREader.GetSize() was expected to return %d, but returned %d instead", 4, ss)
|
t.Fatalf("StreamREader.GetSize() was expected to return %d, but returned %d instead", 4, ss)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(data); i++ {
|
for i := 0; i < len(data); i++ {
|
||||||
ret := sr.GetByte()
|
ret := sr.GetByte()
|
||||||
if ret != data[i] {
|
if ret != data[i] {
|
||||||
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", data[i], ret)
|
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", data[i], ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pos := sr.GetPosition(); pos != uint64(i+1) {
|
if pos := sr.GetPosition(); pos != uint64(i+1) {
|
||||||
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", i, pos)
|
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", i, pos)
|
||||||
}
|
}
|
||||||
@ -28,16 +32,20 @@ func TestStreamReaderWord(t *testing.T) {
|
|||||||
data := []byte{0x78, 0x56, 0x34, 0x12}
|
data := []byte{0x78, 0x56, 0x34, 0x12}
|
||||||
sr := CreateStreamReader(data)
|
sr := CreateStreamReader(data)
|
||||||
ret := sr.GetUInt16()
|
ret := sr.GetUInt16()
|
||||||
|
|
||||||
if ret != 0x5678 {
|
if ret != 0x5678 {
|
||||||
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x5678, ret)
|
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x5678, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pos := sr.GetPosition(); pos != 2 {
|
if pos := sr.GetPosition(); pos != 2 {
|
||||||
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 2, pos)
|
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 2, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sr.GetUInt16()
|
ret = sr.GetUInt16()
|
||||||
if ret != 0x1234 {
|
if ret != 0x1234 {
|
||||||
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x1234, ret)
|
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x1234, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pos := sr.GetPosition(); pos != 4 {
|
if pos := sr.GetPosition(); pos != 4 {
|
||||||
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 4, pos)
|
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 4, pos)
|
||||||
}
|
}
|
||||||
@ -47,9 +55,11 @@ func TestStreamReaderDword(t *testing.T) {
|
|||||||
data := []byte{0x78, 0x56, 0x34, 0x12}
|
data := []byte{0x78, 0x56, 0x34, 0x12}
|
||||||
sr := CreateStreamReader(data)
|
sr := CreateStreamReader(data)
|
||||||
ret := sr.GetUInt32()
|
ret := sr.GetUInt32()
|
||||||
|
|
||||||
if ret != 0x12345678 {
|
if ret != 0x12345678 {
|
||||||
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x12345678, ret)
|
t.Fatalf("StreamReader.GetDword() was expected to return %X, but returned %X instead", 0x12345678, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pos := sr.GetPosition(); pos != 4 {
|
if pos := sr.GetPosition(); pos != 4 {
|
||||||
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 4, pos)
|
t.Fatalf("StreamReader.GetPosition() should be at %d, but was at %d instead", 4, pos)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ func CreateStreamWriter() *StreamWriter {
|
|||||||
result := &StreamWriter{
|
result := &StreamWriter{
|
||||||
data: new(bytes.Buffer),
|
data: new(bytes.Buffer),
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,11 @@ import (
|
|||||||
func TestStreamWriterByte(t *testing.T) {
|
func TestStreamWriterByte(t *testing.T) {
|
||||||
sr := CreateStreamWriter()
|
sr := CreateStreamWriter()
|
||||||
data := []byte{0x12, 0x34, 0x56, 0x78}
|
data := []byte{0x12, 0x34, 0x56, 0x78}
|
||||||
|
|
||||||
for _, d := range data {
|
for _, d := range data {
|
||||||
sr.PushByte(d)
|
sr.PushByte(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
output := sr.GetBytes()
|
output := sr.GetBytes()
|
||||||
for i, d := range data {
|
for i, d := range data {
|
||||||
if output[i] != d {
|
if output[i] != d {
|
||||||
@ -21,8 +23,10 @@ func TestStreamWriterByte(t *testing.T) {
|
|||||||
func TestStreamWriterWord(t *testing.T) {
|
func TestStreamWriterWord(t *testing.T) {
|
||||||
sr := CreateStreamWriter()
|
sr := CreateStreamWriter()
|
||||||
data := []byte{0x12, 0x34, 0x56, 0x78}
|
data := []byte{0x12, 0x34, 0x56, 0x78}
|
||||||
|
|
||||||
sr.PushUint16(0x3412)
|
sr.PushUint16(0x3412)
|
||||||
sr.PushUint16(0x7856)
|
sr.PushUint16(0x7856)
|
||||||
|
|
||||||
output := sr.GetBytes()
|
output := sr.GetBytes()
|
||||||
for i, d := range data {
|
for i, d := range data {
|
||||||
if output[i] != d {
|
if output[i] != d {
|
||||||
@ -34,7 +38,9 @@ func TestStreamWriterWord(t *testing.T) {
|
|||||||
func TestStreamWriterDword(t *testing.T) {
|
func TestStreamWriterDword(t *testing.T) {
|
||||||
sr := CreateStreamWriter()
|
sr := CreateStreamWriter()
|
||||||
data := []byte{0x12, 0x34, 0x56, 0x78}
|
data := []byte{0x12, 0x34, 0x56, 0x78}
|
||||||
|
|
||||||
sr.PushUint32(0x78563412)
|
sr.PushUint32(0x78563412)
|
||||||
|
|
||||||
output := sr.GetBytes()
|
output := sr.GetBytes()
|
||||||
for i, d := range data {
|
for i, d := range data {
|
||||||
if output[i] != d {
|
if output[i] != d {
|
||||||
|
@ -15,14 +15,17 @@ func AsterToEmpty(text string) string {
|
|||||||
if strings.HasPrefix(text, "*") {
|
if strings.HasPrefix(text, "*") {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmptyToZero converts empty strings to "0" and leaves non-empty strings as is, for use before converting numerical data which equates empty to zero
|
// EmptyToZero converts empty strings to "0" and leaves non-empty strings as is,
|
||||||
|
// for use before converting numerical data which equates empty to zero
|
||||||
func EmptyToZero(text string) string {
|
func EmptyToZero(text string) string {
|
||||||
if text == "" || text == " " {
|
if text == "" || text == " " {
|
||||||
return "0"
|
return "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +35,7 @@ func StringToInt(text string) int {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +47,7 @@ func StringToUint(text string) uint {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return uint(result)
|
return uint(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,9 +57,11 @@ func StringToUint8(text string) uint8 {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if result < 0 || result > 255 {
|
if result < 0 || result > 255 {
|
||||||
panic(fmt.Sprintf("value %d out of range of byte", result))
|
panic(fmt.Sprintf("value %d out of range of byte", result))
|
||||||
}
|
}
|
||||||
|
|
||||||
return uint8(result)
|
return uint8(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,16 +71,16 @@ func StringToInt8(text string) int8 {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if result < -128 || result > 122 {
|
if result < -128 || result > 122 {
|
||||||
panic(fmt.Sprintf("value %d out of range of a signed byte", result))
|
panic(fmt.Sprintf("value %d out of range of a signed byte", result))
|
||||||
}
|
}
|
||||||
|
|
||||||
return int8(result)
|
return int8(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringToFloat64 converts a string to a float64
|
// Utf16BytesToString converts a utf16 byte array to string
|
||||||
|
|
||||||
func Utf16BytesToString(b []byte) (string, error) {
|
func Utf16BytesToString(b []byte) (string, error) {
|
||||||
|
|
||||||
if len(b)%2 != 0 {
|
if len(b)%2 != 0 {
|
||||||
return "", fmt.Errorf("must have even length byte slice")
|
return "", fmt.Errorf("must have even length byte slice")
|
||||||
}
|
}
|
||||||
@ -95,40 +102,43 @@ func Utf16BytesToString(b []byte) (string, error) {
|
|||||||
return ret.String(), nil
|
return ret.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CombineStrings(input []string) string {
|
// SplitIntoLinesWithMaxWidth splits the given string into lines considering the given maxChars
|
||||||
return strings.Join(input, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func SplitIntoLinesWithMaxWidth(fullSentence string, maxChars int) []string {
|
func SplitIntoLinesWithMaxWidth(fullSentence string, maxChars int) []string {
|
||||||
lines := make([]string, 0)
|
lines := make([]string, 0)
|
||||||
line := ""
|
line := ""
|
||||||
totalLength := 0
|
totalLength := 0
|
||||||
words := strings.Split(fullSentence, " ")
|
words := strings.Split(fullSentence, " ")
|
||||||
|
|
||||||
if len(words[0]) > maxChars {
|
if len(words[0]) > maxChars {
|
||||||
// mostly happened within CJK characters (no whitespace)
|
// mostly happened within CJK characters (no whitespace)
|
||||||
return splitCjkIntoChunks(fullSentence, maxChars)
|
return splitCjkIntoChunks(fullSentence, maxChars)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, word := range words {
|
for _, word := range words {
|
||||||
totalLength += 1 + len(word)
|
totalLength += 1 + len(word)
|
||||||
if totalLength > maxChars {
|
if totalLength > maxChars {
|
||||||
totalLength = len(word)
|
totalLength = len(word)
|
||||||
|
|
||||||
lines = append(lines, line)
|
lines = append(lines, line)
|
||||||
line = ""
|
line = ""
|
||||||
} else {
|
} else {
|
||||||
line += " "
|
line += " "
|
||||||
}
|
}
|
||||||
|
|
||||||
line += word
|
line += word
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(line) > 0 {
|
if len(line) > 0 {
|
||||||
lines = append(lines, line)
|
lines = append(lines, line)
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitCjkIntoChunks(str string, chars int) []string {
|
func splitCjkIntoChunks(str string, chars int) []string {
|
||||||
chunks := make([]string, chars/len(str))
|
chunks := make([]string, chars/len(str))
|
||||||
i, count := 0, 0
|
i, count := 0, 0
|
||||||
|
|
||||||
for j, ch := range str {
|
for j, ch := range str {
|
||||||
if ch < unicode.MaxLatin1 {
|
if ch < unicode.MaxLatin1 {
|
||||||
count++
|
count++
|
||||||
@ -136,10 +146,12 @@ func splitCjkIntoChunks(str string, chars int) []string {
|
|||||||
// assume we're truncating CJK characters
|
// assume we're truncating CJK characters
|
||||||
count += 2
|
count += 2
|
||||||
}
|
}
|
||||||
|
|
||||||
if count >= chars {
|
if count >= chars {
|
||||||
chunks = append(chunks, str[i:j])
|
chunks = append(chunks, str[i:j])
|
||||||
i, count = j, 0
|
i, count = j, 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(chunks, str[i:])
|
return append(chunks, str[i:])
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ type textDictionaryHashEntry struct {
|
|||||||
|
|
||||||
var lookupTable map[string]string
|
var lookupTable map[string]string
|
||||||
|
|
||||||
|
// TranslateString returns the translation of the given string
|
||||||
func TranslateString(key string) string {
|
func TranslateString(key string) string {
|
||||||
result, ok := lookupTable[key]
|
result, ok := lookupTable[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -23,24 +24,16 @@ func TranslateString(key string) string {
|
|||||||
// log.Panicf("Could not find a string for the key '%s'", key)
|
// log.Panicf("Could not find a string for the key '%s'", key)
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDictionaryEntryCount() int {
|
// LoadTextDictionary loads the text dictionary from the given data
|
||||||
if lookupTable == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return len(lookupTable)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetTranslationMap() map[string]string {
|
|
||||||
return lookupTable
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadTextDictionary(dictionaryData []byte) {
|
func LoadTextDictionary(dictionaryData []byte) {
|
||||||
if lookupTable == nil {
|
if lookupTable == nil {
|
||||||
lookupTable = make(map[string]string)
|
lookupTable = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
br := CreateStreamReader(dictionaryData)
|
br := CreateStreamReader(dictionaryData)
|
||||||
// CRC
|
// CRC
|
||||||
br.ReadBytes(2)
|
br.ReadBytes(2)
|
||||||
@ -50,6 +43,7 @@ func LoadTextDictionary(dictionaryData []byte) {
|
|||||||
if _, err := br.ReadByte(); err != nil {
|
if _, err := br.ReadByte(); err != nil {
|
||||||
log.Fatal("Error reading Version record")
|
log.Fatal("Error reading Version record")
|
||||||
}
|
}
|
||||||
|
|
||||||
br.GetUInt32() // StringOffset
|
br.GetUInt32() // StringOffset
|
||||||
br.GetUInt32() // When the number of times you have missed a match with a hash key equals this value, you give up because it is not there.
|
br.GetUInt32() // When the number of times you have missed a match with a hash key equals this value, you give up because it is not there.
|
||||||
br.GetUInt32() // FileSize
|
br.GetUInt32() // FileSize
|
||||||
@ -75,37 +69,31 @@ func LoadTextDictionary(dictionaryData []byte) {
|
|||||||
if !hashEntry.IsActive {
|
if !hashEntry.IsActive {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
br.SetPosition(uint64(hashEntry.NameString))
|
br.SetPosition(uint64(hashEntry.NameString))
|
||||||
nameVal := br.ReadBytes(int(hashEntry.NameLength - 1))
|
nameVal := br.ReadBytes(int(hashEntry.NameLength - 1))
|
||||||
value := string(nameVal)
|
value := string(nameVal)
|
||||||
|
|
||||||
br.SetPosition(uint64(hashEntry.IndexString))
|
br.SetPosition(uint64(hashEntry.IndexString))
|
||||||
|
|
||||||
key := ""
|
key := ""
|
||||||
|
|
||||||
for {
|
for {
|
||||||
b := br.GetByte()
|
b := br.GetByte()
|
||||||
if b == 0 {
|
if b == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
key += string(b)
|
key += string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
if key == "x" || key == "X" {
|
if key == "x" || key == "X" {
|
||||||
key = "#" + strconv.Itoa(idx)
|
key = "#" + strconv.Itoa(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, exists := lookupTable[key]
|
_, exists := lookupTable[key]
|
||||||
if !exists {
|
if !exists {
|
||||||
lookupTable[key] = value
|
lookupTable[key] = value
|
||||||
|
|
||||||
}
|
}
|
||||||
// Use the following code to write out the values
|
|
||||||
/*=
|
|
||||||
f, err := os.OpenFile(`C:\Users\lunat\Desktop\D2\langdict.txt`,
|
|
||||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
if _, err := f.WriteString("\n[" + key + "] " + value); err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user