2020-01-26 00:39:13 -05:00
|
|
|
package d2dt1
|
|
|
|
|
|
|
|
import (
|
2020-02-26 08:39:38 -05:00
|
|
|
"fmt"
|
2020-01-26 00:39:13 -05:00
|
|
|
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
|
|
|
)
|
|
|
|
|
2020-06-28 22:32:34 -04:00
|
|
|
// DT1 represents a DT1 file.
|
2020-01-26 00:39:13 -05:00
|
|
|
type DT1 struct {
|
|
|
|
Tiles []Tile
|
|
|
|
}
|
|
|
|
|
2020-06-24 10:13:11 -04:00
|
|
|
// BlockDataFormat represents the format of the block data
|
2020-01-26 00:39:13 -05:00
|
|
|
type BlockDataFormat int16
|
|
|
|
|
|
|
|
const (
|
2020-06-28 22:32:34 -04:00
|
|
|
// BlockFormatRLE specifies the block format is RLE encoded
|
|
|
|
BlockFormatRLE BlockDataFormat = 0
|
|
|
|
|
|
|
|
// BlockFormatIsometric specifies the block format isometrically encoded
|
|
|
|
BlockFormatIsometric BlockDataFormat = 1
|
2020-01-26 00:39:13 -05:00
|
|
|
)
|
|
|
|
|
2020-06-24 10:13:11 -04:00
|
|
|
// LoadDT1 loads a DT1 record
|
2020-06-28 22:32:34 -04:00
|
|
|
//nolint:funlen Can't reduce
|
2020-02-26 08:39:38 -05:00
|
|
|
func LoadDT1(fileData []byte) (*DT1, error) {
|
|
|
|
result := &DT1{}
|
2020-01-26 00:39:13 -05:00
|
|
|
br := d2common.CreateStreamReader(fileData)
|
|
|
|
ver1 := br.GetInt32()
|
|
|
|
ver2 := br.GetInt32()
|
2020-06-24 10:13:11 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
if ver1 != 7 || ver2 != 6 {
|
2020-06-22 11:53:44 -04:00
|
|
|
return nil, fmt.Errorf("expected to have a version of 7.6, but got %d.%d instead", ver1, ver2)
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|
2020-06-24 10:13:11 -04:00
|
|
|
|
|
|
|
br.SkipBytes(260) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
numberOfTiles := br.GetInt32()
|
|
|
|
br.SetPosition(uint64(br.GetInt32()))
|
2020-06-24 10:13:11 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
result.Tiles = make([]Tile, numberOfTiles)
|
2020-06-24 10:13:11 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
for tileIdx := range result.Tiles {
|
|
|
|
newTile := Tile{}
|
|
|
|
newTile.Direction = br.GetInt32()
|
|
|
|
newTile.RoofHeight = br.GetInt16()
|
|
|
|
newTile.MaterialFlags = NewMaterialFlags(br.GetUInt16())
|
|
|
|
newTile.Height = br.GetInt32()
|
|
|
|
newTile.Width = br.GetInt32()
|
2020-06-24 10:13:11 -04:00
|
|
|
|
|
|
|
br.SkipBytes(4) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
newTile.Type = br.GetInt32()
|
|
|
|
newTile.Style = br.GetInt32()
|
|
|
|
newTile.Sequence = br.GetInt32()
|
|
|
|
newTile.RarityFrameIndex = br.GetInt32()
|
2020-06-24 10:13:11 -04:00
|
|
|
|
|
|
|
br.SkipBytes(4) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
for i := range newTile.SubTileFlags {
|
|
|
|
newTile.SubTileFlags[i] = NewSubTileFlags(br.GetByte())
|
|
|
|
}
|
2020-06-24 10:13:11 -04:00
|
|
|
|
|
|
|
br.SkipBytes(7) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
newTile.blockHeaderPointer = br.GetInt32()
|
|
|
|
newTile.blockHeaderSize = br.GetInt32()
|
|
|
|
newTile.Blocks = make([]Block, br.GetInt32())
|
2020-06-24 10:13:11 -04:00
|
|
|
|
|
|
|
br.SkipBytes(12) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
result.Tiles[tileIdx] = newTile
|
|
|
|
}
|
2020-06-24 10:13:11 -04:00
|
|
|
|
|
|
|
for tileIdx := range result.Tiles {
|
|
|
|
tile := &result.Tiles[tileIdx]
|
2020-01-26 00:39:13 -05:00
|
|
|
br.SetPosition(uint64(tile.blockHeaderPointer))
|
2020-06-24 10:13:11 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
for blockIdx := range tile.Blocks {
|
|
|
|
result.Tiles[tileIdx].Blocks[blockIdx].X = br.GetInt16()
|
|
|
|
result.Tiles[tileIdx].Blocks[blockIdx].Y = br.GetInt16()
|
2020-06-24 10:13:11 -04:00
|
|
|
|
|
|
|
br.SkipBytes(2) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
result.Tiles[tileIdx].Blocks[blockIdx].GridX = br.GetByte()
|
|
|
|
result.Tiles[tileIdx].Blocks[blockIdx].GridY = br.GetByte()
|
|
|
|
formatValue := br.GetInt16()
|
2020-06-24 10:13:11 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
if formatValue == 1 {
|
|
|
|
result.Tiles[tileIdx].Blocks[blockIdx].Format = BlockFormatIsometric
|
|
|
|
} else {
|
|
|
|
result.Tiles[tileIdx].Blocks[blockIdx].Format = BlockFormatRLE
|
|
|
|
}
|
2020-06-24 10:13:11 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
result.Tiles[tileIdx].Blocks[blockIdx].Length = br.GetInt32()
|
2020-06-24 10:13:11 -04:00
|
|
|
|
|
|
|
br.SkipBytes(2) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
result.Tiles[tileIdx].Blocks[blockIdx].FileOffset = br.GetInt32()
|
|
|
|
}
|
2020-06-24 10:13:11 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
for blockIndex, block := range tile.Blocks {
|
|
|
|
br.SetPosition(uint64(tile.blockHeaderPointer + block.FileOffset))
|
2020-06-20 21:07:36 -04:00
|
|
|
encodedData := br.ReadBytes(int(block.Length))
|
2020-01-26 00:39:13 -05:00
|
|
|
tile.Blocks[blockIndex].EncodedData = encodedData
|
|
|
|
}
|
|
|
|
}
|
2020-06-24 10:13:11 -04:00
|
|
|
|
2020-02-26 08:39:38 -05:00
|
|
|
return result, nil
|
2020-01-26 00:39:13 -05:00
|
|
|
}
|