package Map import ( "log" "github.com/OpenDiablo2/OpenDiablo2/Common" ) // https://d2mods.info/forum/viewtopic.php?t=65163 type Block struct { X int16 Y int16 GridX byte GridY byte Format BlockDataFormat EncodedData []byte Length int32 FileOffset int32 } type Tile struct { Direction int32 RoofHeight int16 SoundIndex byte Animated bool Height int32 Width int32 Orientation int32 MainIndex int32 SubIndex int32 RarityFrameIndex int32 SubTileFlags [25]byte blockHeaderPointer int32 blockHeaderSize int32 Blocks []Block } type DT1 struct { Tiles []Tile } type BlockDataFormat int16 const ( BlockFormatRLE BlockDataFormat = 0 // Not 1 BlockFormatIsometric BlockDataFormat = 1 ) func LoadDT1(path string, fileProvider Common.FileProvider) *DT1 { result := &DT1{} fileData := fileProvider.LoadFile(path) br := Common.CreateStreamReader(fileData) ver1 := br.GetInt32() ver2 := br.GetInt32() if ver1 != 7 || ver2 != 6 { log.Panicf("Expected %s to have a version of 7.6, but got %d.%d instead", path, ver1, ver2) } br.SkipBytes(260) numberOfTiles := br.GetInt32() br.SetPosition(uint64(br.GetInt32())) result.Tiles = make([]Tile, numberOfTiles) for tileIdx := range result.Tiles { newTile := Tile{} newTile.Direction = br.GetInt32() newTile.RoofHeight = br.GetInt16() newTile.SoundIndex = br.GetByte() newTile.Animated = br.GetByte() == 1 newTile.Height = br.GetInt32() newTile.Width = br.GetInt32() br.SkipBytes(4) newTile.Orientation = br.GetInt32() newTile.MainIndex = br.GetInt32() newTile.SubIndex = br.GetInt32() newTile.RarityFrameIndex = br.GetInt32() br.SkipBytes(4) for i := range newTile.SubTileFlags { newTile.SubTileFlags[i] = br.GetByte() } br.SkipBytes(7) newTile.blockHeaderPointer = br.GetInt32() newTile.blockHeaderSize = br.GetInt32() newTile.Blocks = make([]Block, br.GetInt32()) br.SkipBytes(12) result.Tiles[tileIdx] = newTile } for tileIdx, tile := range result.Tiles { br.SetPosition(uint64(tile.blockHeaderPointer)) for blockIdx := range tile.Blocks { result.Tiles[tileIdx].Blocks[blockIdx].X = br.GetInt16() result.Tiles[tileIdx].Blocks[blockIdx].Y = br.GetInt16() br.SkipBytes(2) result.Tiles[tileIdx].Blocks[blockIdx].GridX = br.GetByte() result.Tiles[tileIdx].Blocks[blockIdx].GridY = br.GetByte() formatValue := br.GetInt16() if formatValue == 1 { result.Tiles[tileIdx].Blocks[blockIdx].Format = BlockFormatIsometric } else { result.Tiles[tileIdx].Blocks[blockIdx].Format = BlockFormatRLE } result.Tiles[tileIdx].Blocks[blockIdx].Length = br.GetInt32() br.SkipBytes(2) result.Tiles[tileIdx].Blocks[blockIdx].FileOffset = br.GetInt32() } for blockIndex, block := range tile.Blocks { br.SetPosition(uint64(tile.blockHeaderPointer + block.FileOffset)) encodedData, _ := br.ReadBytes(int(block.Length)) tile.Blocks[blockIndex].EncodedData = encodedData } } return result }