mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-17 18:06:03 -05:00
Ds1 refactor: test bugs + descriptive errors + SetNumberOfWall/FloorLayers (#6)
* ds1 refactor: - removed DS1.layerStreamTypes field - written unit test for setupStreamLayerTypes method - added more descriptive error messages for LoadDS1 (and submethods) * ds1 refactor: added some missing error messages * ds1 refactor: fixed test bugs * ds1 refactor: removed unnecessary c1. and c2. comments in ds1_test errors * ds1 refactor: removed fmt from ds1_test * ds1 refactor: fixed bug with SetTiles test + lintfix * ds1 refactor: SetNumberOfWalls * ds1 refactor: SetTile(s) now changes walls/floors length if neccesary * ds1 refactor: removed unnecessary debugging fmt * ds1 refactor: added substitution layer and object with paths to example data Co-authored-by: M. Sz <mszeptuch@protonmail.com>
This commit is contained in:
parent
46d2bc6559
commit
5e62b12bc4
@ -58,7 +58,6 @@ type DS1 struct {
|
|||||||
|
|
||||||
dirty bool // when modifying tiles, need to perform upkeep on ds1 state
|
dirty bool // when modifying tiles, need to perform upkeep on ds1 state
|
||||||
unknown1 []byte
|
unknown1 []byte
|
||||||
layerStreamTypes []d2enum.LayerStreamType
|
|
||||||
unknown2 uint32
|
unknown2 uint32
|
||||||
npcIndexes []int
|
npcIndexes []int
|
||||||
}
|
}
|
||||||
@ -135,7 +134,6 @@ func (ds1 *DS1) SetTiles(tiles [][]Tile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ds1.tiles = tiles
|
ds1.tiles = tiles
|
||||||
ds1.layerStreamTypes = ds1.setupStreamLayerTypes()
|
|
||||||
ds1.dirty = true
|
ds1.dirty = true
|
||||||
ds1.update()
|
ds1.update()
|
||||||
}
|
}
|
||||||
@ -165,6 +163,7 @@ func (ds1 *DS1) SetTile(x, y int, t *Tile) {
|
|||||||
|
|
||||||
ds1.tiles[y][x] = *t
|
ds1.tiles[y][x] = *t
|
||||||
ds1.dirty = true
|
ds1.dirty = true
|
||||||
|
ds1.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version returns the ds1's version
|
// Version returns the ds1's version
|
||||||
@ -283,8 +282,8 @@ func (ds1 *DS1) Size() (w, h int) {
|
|||||||
return int(ds1.width), int(ds1.height)
|
return int(ds1.width), int(ds1.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setSize force sets the ds1's size (width,height)
|
// SetSize force sets the ds1's size (width,height)
|
||||||
func (ds1 *DS1) setSize(w, h int) {
|
func (ds1 *DS1) SetSize(w, h int) {
|
||||||
ds1.SetWidth(w)
|
ds1.SetWidth(w)
|
||||||
ds1.SetHeight(h)
|
ds1.SetHeight(h)
|
||||||
ds1.width, ds1.height = int32(w), int32(h)
|
ds1.width, ds1.height = int32(w), int32(h)
|
||||||
@ -323,6 +322,38 @@ func (ds1 *DS1) NumberOfWallLayers() int {
|
|||||||
return int(ds1.numberOfWallLayers)
|
return int(ds1.numberOfWallLayers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNumberOfWallLayers sets new number of tiles' walls
|
||||||
|
func (ds1 *DS1) SetNumberOfWallLayers(n int32) {
|
||||||
|
for y := range ds1.tiles {
|
||||||
|
for x := range ds1.tiles[y] {
|
||||||
|
for v := int32(0); v < n-int32(len(ds1.tiles[y][x].Walls)); v++ {
|
||||||
|
ds1.tiles[y][x].Walls = append(ds1.tiles[y][x].Walls, Wall{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if n = number of walls, do nothing
|
||||||
|
if n == ds1.numberOfWallLayers {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ds1.dirty = true
|
||||||
|
defer ds1.update()
|
||||||
|
|
||||||
|
for y := range ds1.tiles {
|
||||||
|
for x := range ds1.tiles[y] {
|
||||||
|
newWalls := make([]Wall, n)
|
||||||
|
for v := int32(0); v < n; v++ {
|
||||||
|
newWalls[v] = ds1.tiles[y][x].Walls[v]
|
||||||
|
}
|
||||||
|
|
||||||
|
ds1.tiles[y][x].Walls = newWalls
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ds1.numberOfWallLayers = n
|
||||||
|
}
|
||||||
|
|
||||||
// NumberOfFloorLayers returns the number of floor layers per tile
|
// NumberOfFloorLayers returns the number of floor layers per tile
|
||||||
func (ds1 *DS1) NumberOfFloorLayers() int {
|
func (ds1 *DS1) NumberOfFloorLayers() int {
|
||||||
if ds1.dirty {
|
if ds1.dirty {
|
||||||
@ -332,6 +363,41 @@ func (ds1 *DS1) NumberOfFloorLayers() int {
|
|||||||
return int(ds1.numberOfFloorLayers)
|
return int(ds1.numberOfFloorLayers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNumberOfFloorLayers sets new number of tiles' floors
|
||||||
|
func (ds1 *DS1) SetNumberOfFloorLayers(n int32) {
|
||||||
|
// calculate, how much walls is missing
|
||||||
|
missingFloors := n - ds1.numberOfFloorLayers
|
||||||
|
|
||||||
|
for y := range ds1.tiles {
|
||||||
|
for x := range ds1.tiles[y] {
|
||||||
|
for v := int32(0); v < missingFloors; v++ {
|
||||||
|
ds1.tiles[y][x].Floors = append(ds1.tiles[y][x].Floors, Floor{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if n = number of walls, do nothing
|
||||||
|
if n == ds1.numberOfFloorLayers {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ds1.dirty = true
|
||||||
|
defer ds1.update()
|
||||||
|
|
||||||
|
for y := range ds1.tiles {
|
||||||
|
for x := range ds1.tiles[y] {
|
||||||
|
newFloors := make([]Floor, n)
|
||||||
|
for v := int32(0); v < n; v++ {
|
||||||
|
newFloors[v] = ds1.tiles[y][x].Floors[v]
|
||||||
|
}
|
||||||
|
|
||||||
|
ds1.tiles[y][x].Floors = newFloors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ds1.numberOfFloorLayers = n
|
||||||
|
}
|
||||||
|
|
||||||
// NumberOfShadowLayers returns the number of shadow layers per tile
|
// NumberOfShadowLayers returns the number of shadow layers per tile
|
||||||
func (ds1 *DS1) NumberOfShadowLayers() int {
|
func (ds1 *DS1) NumberOfShadowLayers() int {
|
||||||
if ds1.dirty {
|
if ds1.dirty {
|
||||||
@ -365,7 +431,18 @@ func (ds1 *DS1) update() {
|
|||||||
ds1.enforceAllTileLayersMatch()
|
ds1.enforceAllTileLayersMatch()
|
||||||
ds1.updateLayerCounts()
|
ds1.updateLayerCounts()
|
||||||
|
|
||||||
ds1.setSize(len(ds1.tiles[0]), len(ds1.tiles))
|
ds1.SetSize(len(ds1.tiles[0]), len(ds1.tiles))
|
||||||
|
|
||||||
|
maxWalls := ds1.numberOfWallLayers
|
||||||
|
for y := range ds1.tiles {
|
||||||
|
for x := range ds1.tiles[y] {
|
||||||
|
if len(ds1.tiles[y][x].Walls) > int(maxWalls) {
|
||||||
|
maxWalls = int32(len(ds1.tiles[y][x].Walls))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ds1.SetNumberOfWallLayers(maxWalls)
|
||||||
|
|
||||||
ds1.dirty = false
|
ds1.dirty = false
|
||||||
}
|
}
|
||||||
@ -405,35 +482,33 @@ func LoadDS1(fileData []byte) (*DS1, error) {
|
|||||||
|
|
||||||
err = ds1.loadHeader(br)
|
err = ds1.loadHeader(br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("loading header: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ds1.version >= v9 && ds1.version <= v13 {
|
if ds1.version >= v9 && ds1.version <= v13 {
|
||||||
// Skipping two dwords because they are "meaningless"?
|
// Skipping two dwords because they are "meaningless"?
|
||||||
ds1.unknown1, err = br.ReadBytes(unknown1BytesCount)
|
ds1.unknown1, err = br.ReadBytes(unknown1BytesCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("reading unknown1: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ds1.version >= v4 {
|
if ds1.version >= v4 {
|
||||||
ds1.numberOfWallLayers, err = br.ReadInt32()
|
ds1.numberOfWallLayers, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("reading wall number: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ds1.version >= v16 {
|
if ds1.version >= v16 {
|
||||||
ds1.numberOfFloorLayers, err = br.ReadInt32()
|
ds1.numberOfFloorLayers, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("reading number of floors: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ds1.numberOfFloorLayers = 1
|
ds1.numberOfFloorLayers = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.layerStreamTypes = ds1.setupStreamLayerTypes()
|
|
||||||
|
|
||||||
ds1.tiles = make([][]Tile, ds1.height)
|
ds1.tiles = make([][]Tile, ds1.height)
|
||||||
|
|
||||||
for y := range ds1.tiles {
|
for y := range ds1.tiles {
|
||||||
@ -448,22 +523,22 @@ func LoadDS1(fileData []byte) (*DS1, error) {
|
|||||||
|
|
||||||
err = ds1.loadLayerStreams(br)
|
err = ds1.loadLayerStreams(br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("loading layer streams: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ds1.loadobjects(br)
|
err = ds1.loadObjects(br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("loading objects: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ds1.loadSubstitutions(br)
|
err = ds1.loadSubstitutions(br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("loading substitutions: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ds1.loadNPCs(br)
|
err = ds1.loadNPCs(br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("loading npc's: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ds1, nil
|
return ds1, nil
|
||||||
@ -474,17 +549,17 @@ func (ds1 *DS1) loadHeader(br *d2datautils.StreamReader) error {
|
|||||||
|
|
||||||
ds1.version, err = br.ReadInt32()
|
ds1.version, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading version: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.width, err = br.ReadInt32()
|
ds1.width, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading width: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.height, err = br.ReadInt32()
|
ds1.height, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading height: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.width++
|
ds1.width++
|
||||||
@ -493,7 +568,7 @@ func (ds1 *DS1) loadHeader(br *d2datautils.StreamReader) error {
|
|||||||
if ds1.version >= v8 {
|
if ds1.version >= v8 {
|
||||||
ds1.act, err = br.ReadInt32()
|
ds1.act, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading act: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.act = d2math.MinInt32(d2enum.ActsNumber, ds1.act+1)
|
ds1.act = d2math.MinInt32(d2enum.ActsNumber, ds1.act+1)
|
||||||
@ -502,7 +577,7 @@ func (ds1 *DS1) loadHeader(br *d2datautils.StreamReader) error {
|
|||||||
if ds1.version >= v10 {
|
if ds1.version >= v10 {
|
||||||
ds1.substitutionType, err = br.ReadInt32()
|
ds1.substitutionType, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading substitution type: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ds1.substitutionType == 1 || ds1.substitutionType == 2 {
|
if ds1.substitutionType == 1 || ds1.substitutionType == 2 {
|
||||||
@ -512,7 +587,7 @@ func (ds1 *DS1) loadHeader(br *d2datautils.StreamReader) error {
|
|||||||
|
|
||||||
err = ds1.loadFileList(br)
|
err = ds1.loadFileList(br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("loading file list: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -523,7 +598,7 @@ func (ds1 *DS1) loadFileList(br *d2datautils.StreamReader) error {
|
|||||||
// These files reference things that don't exist anymore :-?
|
// These files reference things that don't exist anymore :-?
|
||||||
numberOfFiles, err := br.ReadInt32()
|
numberOfFiles, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading number of files: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.files = make([]string, numberOfFiles)
|
ds1.files = make([]string, numberOfFiles)
|
||||||
@ -534,7 +609,7 @@ func (ds1 *DS1) loadFileList(br *d2datautils.StreamReader) error {
|
|||||||
for {
|
for {
|
||||||
ch, err := br.ReadByte()
|
ch, err := br.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading file character: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ch == 0 {
|
if ch == 0 {
|
||||||
@ -549,13 +624,13 @@ func (ds1 *DS1) loadFileList(br *d2datautils.StreamReader) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds1 *DS1) loadobjects(br *d2datautils.StreamReader) error {
|
func (ds1 *DS1) loadObjects(br *d2datautils.StreamReader) error {
|
||||||
if ds1.version < v2 {
|
if ds1.version < v2 {
|
||||||
ds1.objects = make([]Object, 0)
|
ds1.objects = make([]Object, 0)
|
||||||
} else {
|
} else {
|
||||||
numberOfobjects, err := br.ReadInt32()
|
numberOfobjects, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading number of objects: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.objects = make([]Object, numberOfobjects)
|
ds1.objects = make([]Object, numberOfobjects)
|
||||||
@ -564,27 +639,27 @@ func (ds1 *DS1) loadobjects(br *d2datautils.StreamReader) error {
|
|||||||
obj := Object{}
|
obj := Object{}
|
||||||
objType, err := br.ReadInt32()
|
objType, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading object's %d type: %v", objIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
objID, err := br.ReadInt32()
|
objID, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading object's %d ID: %v", objIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
objX, err := br.ReadInt32()
|
objX, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading object's %d X: %v", objIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
objY, err := br.ReadInt32()
|
objY, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading object's %d Y: %v", objY, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
objFlags, err := br.ReadInt32()
|
objFlags, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading object's %d flags: %v", objIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.Type = int(objType)
|
obj.Type = int(objType)
|
||||||
@ -613,13 +688,13 @@ func (ds1 *DS1) loadSubstitutions(br *d2datautils.StreamReader) error {
|
|||||||
if ds1.version >= v18 {
|
if ds1.version >= v18 {
|
||||||
ds1.unknown2, err = br.ReadUInt32()
|
ds1.unknown2, err = br.ReadUInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading unknown 2: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
numberOfSubGroups, err := br.ReadInt32()
|
numberOfSubGroups, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading number of sub groups: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.substitutionGroups = make([]SubstitutionGroup, numberOfSubGroups)
|
ds1.substitutionGroups = make([]SubstitutionGroup, numberOfSubGroups)
|
||||||
@ -629,27 +704,27 @@ func (ds1 *DS1) loadSubstitutions(br *d2datautils.StreamReader) error {
|
|||||||
|
|
||||||
newSub.TileX, err = br.ReadInt32()
|
newSub.TileX, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading substitution's %d X: %v", subIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newSub.TileY, err = br.ReadInt32()
|
newSub.TileY, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading substitution's %d Y: %v", subIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newSub.WidthInTiles, err = br.ReadInt32()
|
newSub.WidthInTiles, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading substitution's %d W: %v", subIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newSub.HeightInTiles, err = br.ReadInt32()
|
newSub.HeightInTiles, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading substitution's %d H: %v", subIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newSub.Unknown, err = br.ReadInt32()
|
newSub.Unknown, err = br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading substitution's %d unknown: %v", subIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.substitutionGroups[subIdx] = newSub
|
ds1.substitutionGroups[subIdx] = newSub
|
||||||
@ -700,28 +775,28 @@ func (ds1 *DS1) loadNPCs(br *d2datautils.StreamReader) error {
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
if ds1.version < v14 {
|
if ds1.version < v14 {
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
numberOfNpcs, err := br.ReadInt32()
|
numberOfNpcs, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading number of npcs: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for npcIdx := 0; npcIdx < int(numberOfNpcs); npcIdx++ {
|
for npcIdx := 0; npcIdx < int(numberOfNpcs); npcIdx++ {
|
||||||
numPaths, err := br.ReadInt32() // nolint:govet // I want to re-use this error variable
|
numPaths, err := br.ReadInt32() // nolint:govet // I want to re-use this error variable
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading number of paths for npc %d: %v", npcIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
npcX, err := br.ReadInt32()
|
npcX, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading X pos for NPC %d: %v", npcIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
npcY, err := br.ReadInt32()
|
npcY, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading Y pos for NPC %d: %v", npcIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
objIdx := -1
|
objIdx := -1
|
||||||
@ -738,7 +813,7 @@ func (ds1 *DS1) loadNPCs(br *d2datautils.StreamReader) error {
|
|||||||
if objIdx > -1 {
|
if objIdx > -1 {
|
||||||
err = ds1.loadNpcPaths(br, objIdx, int(numPaths))
|
err = ds1.loadNpcPaths(br, objIdx, int(numPaths))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("loading paths for NPC %d: %v", npcIdx, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ds1.version >= v15 {
|
if ds1.version >= v15 {
|
||||||
@ -753,8 +828,6 @@ func (ds1 *DS1) loadNPCs(br *d2datautils.StreamReader) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ds1 *DS1) loadNpcPaths(br *d2datautils.StreamReader, objIdx, numPaths int) error {
|
func (ds1 *DS1) loadNpcPaths(br *d2datautils.StreamReader, objIdx, numPaths int) error {
|
||||||
var err error
|
|
||||||
|
|
||||||
if ds1.objects[objIdx].Paths == nil {
|
if ds1.objects[objIdx].Paths == nil {
|
||||||
ds1.objects[objIdx].Paths = make([]d2path.Path, numPaths)
|
ds1.objects[objIdx].Paths = make([]d2path.Path, numPaths)
|
||||||
}
|
}
|
||||||
@ -764,12 +837,12 @@ func (ds1 *DS1) loadNpcPaths(br *d2datautils.StreamReader, objIdx, numPaths int)
|
|||||||
|
|
||||||
px, err := br.ReadInt32() //nolint:govet // i want to re-use the err variable...
|
px, err := br.ReadInt32() //nolint:govet // i want to re-use the err variable...
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading X point for path %d: %v", pathIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
py, err := br.ReadInt32() //nolint:govet // i want to re-use the err variable...
|
py, err := br.ReadInt32() //nolint:govet // i want to re-use the err variable...
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading Y point for path %d: %v", pathIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newPath.Position = d2vector.NewPosition(float64(px), float64(py))
|
newPath.Position = d2vector.NewPosition(float64(px), float64(py))
|
||||||
@ -777,7 +850,7 @@ func (ds1 *DS1) loadNpcPaths(br *d2datautils.StreamReader, objIdx, numPaths int)
|
|||||||
if ds1.version >= v15 {
|
if ds1.version >= v15 {
|
||||||
action, err := br.ReadInt32()
|
action, err := br.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading action for path %d: %v", pathIdx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newPath.Action = int(action)
|
newPath.Action = int(action)
|
||||||
@ -786,26 +859,24 @@ func (ds1 *DS1) loadNpcPaths(br *d2datautils.StreamReader, objIdx, numPaths int)
|
|||||||
ds1.objects[objIdx].Paths[pathIdx] = newPath
|
ds1.objects[objIdx].Paths[pathIdx] = newPath
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error {
|
func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error {
|
||||||
var err error
|
|
||||||
|
|
||||||
var dirLookup = []int32{
|
var dirLookup = []int32{
|
||||||
0x00, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, 0x05, 0x05, 0x06,
|
0x00, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, 0x05, 0x05, 0x06,
|
||||||
0x06, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
0x06, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
|
||||||
0x0F, 0x10, 0x11, 0x12, 0x14,
|
0x0F, 0x10, 0x11, 0x12, 0x14,
|
||||||
}
|
}
|
||||||
|
|
||||||
for lIdx := range ds1.layerStreamTypes {
|
layerStreamTypes := ds1.setupStreamLayerTypes()
|
||||||
layerStreamType := ds1.layerStreamTypes[lIdx]
|
|
||||||
|
|
||||||
|
for _, layerStreamType := range layerStreamTypes {
|
||||||
for y := 0; y < int(ds1.height); y++ {
|
for y := 0; y < int(ds1.height); y++ {
|
||||||
for x := 0; x < int(ds1.width); x++ {
|
for x := 0; x < int(ds1.width); x++ {
|
||||||
dw, err := br.ReadUInt32() //nolint:govet // i want to re-use the err variable...
|
dw, err := br.ReadUInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("reading layer's dword: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch layerStreamType {
|
switch layerStreamType {
|
||||||
@ -837,7 +908,7 @@ func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal encodes ds1 back to byte slice
|
// Marshal encodes ds1 back to byte slice
|
||||||
@ -919,9 +990,9 @@ func (ds1 *DS1) Marshal() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) {
|
func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) {
|
||||||
for lIdx := range ds1.layerStreamTypes {
|
layerStreamTypes := ds1.setupStreamLayerTypes()
|
||||||
layerStreamType := ds1.layerStreamTypes[lIdx]
|
|
||||||
|
|
||||||
|
for _, layerStreamType := range layerStreamTypes {
|
||||||
for y := 0; y < int(ds1.height); y++ {
|
for y := 0; y < int(ds1.height); y++ {
|
||||||
for x := 0; x < int(ds1.width); x++ {
|
for x := 0; x < int(ds1.width); x++ {
|
||||||
dw := uint32(0)
|
dw := uint32(0)
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2path"
|
||||||
)
|
)
|
||||||
|
|
||||||
func exampleDS1() *DS1 {
|
func exampleDS1() *DS1 {
|
||||||
@ -11,18 +12,38 @@ func exampleDS1() *DS1 {
|
|||||||
files: []string{"a.dt1", "b.dt1"},
|
files: []string{"a.dt1", "b.dt1"},
|
||||||
objects: []Object{
|
objects: []Object{
|
||||||
{0, 0, 0, 0, 0, nil},
|
{0, 0, 0, 0, 0, nil},
|
||||||
{0, 1, 0, 0, 0, nil},
|
{0, 1, 0, 0, 0, []d2path.Path{{}}},
|
||||||
{0, 2, 0, 0, 0, nil},
|
{0, 2, 0, 0, 0, nil},
|
||||||
{0, 3, 0, 0, 0, nil},
|
{0, 3, 0, 0, 0, nil},
|
||||||
},
|
},
|
||||||
tiles: [][]Tile{ // 2x2
|
tiles: [][]Tile{ // 2x2
|
||||||
{
|
{
|
||||||
Tile{[]Floor{{}}, []Wall{{}}, []Shadow{{}}, []Substitution{}},
|
Tile{
|
||||||
Tile{[]Floor{{}}, []Wall{{}}, []Shadow{{}}, []Substitution{}},
|
[]Floor{{}},
|
||||||
|
[]Wall{{}},
|
||||||
|
[]Shadow{{}},
|
||||||
|
[]Substitution{{}},
|
||||||
|
},
|
||||||
|
Tile{
|
||||||
|
[]Floor{{}},
|
||||||
|
[]Wall{{}},
|
||||||
|
[]Shadow{{}},
|
||||||
|
[]Substitution{{}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Tile{[]Floor{{}}, []Wall{{}}, []Shadow{{}}, []Substitution{}},
|
Tile{
|
||||||
Tile{[]Floor{{}}, []Wall{{}}, []Shadow{{}}, []Substitution{}},
|
[]Floor{{}},
|
||||||
|
[]Wall{{}},
|
||||||
|
[]Shadow{{}},
|
||||||
|
[]Substitution{{}},
|
||||||
|
},
|
||||||
|
Tile{
|
||||||
|
[]Floor{{}},
|
||||||
|
[]Wall{{}},
|
||||||
|
[]Shadow{{}},
|
||||||
|
[]Substitution{{}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
substitutionGroups: nil,
|
substitutionGroups: nil,
|
||||||
@ -35,12 +56,6 @@ func exampleDS1() *DS1 {
|
|||||||
numberOfFloorLayers: 1,
|
numberOfFloorLayers: 1,
|
||||||
numberOfShadowLayers: 1,
|
numberOfShadowLayers: 1,
|
||||||
numberOfSubstitutionLayers: 1,
|
numberOfSubstitutionLayers: 1,
|
||||||
layerStreamTypes: []d2enum.LayerStreamType{
|
|
||||||
d2enum.LayerStreamWall1,
|
|
||||||
d2enum.LayerStreamOrientation1,
|
|
||||||
d2enum.LayerStreamFloor1,
|
|
||||||
d2enum.LayerStreamShadow,
|
|
||||||
},
|
|
||||||
npcIndexes: []int{},
|
npcIndexes: []int{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,12 +67,15 @@ func testIfRestorable(ds1 *DS1, test func(ds1 *DS1)) error {
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
data := ds1.Marshal()
|
data := ds1.Marshal()
|
||||||
|
|
||||||
newDS1, err := LoadDS1(data)
|
newDS1, err := LoadDS1(data)
|
||||||
_ = newDS1
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
test(newDS1)
|
test(newDS1)
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDS1_Marshal(t *testing.T) {
|
func TestDS1_Marshal(t *testing.T) {
|
||||||
@ -74,6 +92,10 @@ func TestDS1_Marshal(t *testing.T) {
|
|||||||
if b.width != a.width {
|
if b.width != a.width {
|
||||||
t.Error("new ds1 does not match original")
|
t.Error("new ds1 does not match original")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(b.tiles) != len(a.tiles) {
|
||||||
|
t.Error("new ds1 does not batch original")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDS1_Files(t *testing.T) {
|
func TestDS1_Files(t *testing.T) {
|
||||||
@ -227,22 +249,21 @@ func TestDS1_SetTiles(t *testing.T) {
|
|||||||
|
|
||||||
exampleTile1 := Tile{
|
exampleTile1 := Tile{
|
||||||
Floors: []floorShadow{
|
Floors: []floorShadow{
|
||||||
{0, 0, 2, 3, 4, 55, 33, true, 999},
|
{8, 7, 2, 3, 4, 55, 33, true, 999},
|
||||||
},
|
},
|
||||||
Walls: []Wall{
|
Walls: []Wall{
|
||||||
{2, 3, 4, 5, 3, 2, 3, 0, 33, 99},
|
{2, 3, 4, 5, 3, 2, 3, 0, 33, 99},
|
||||||
|
{2, 3, 4, 5, 3, 2, 3, 0, 33, 99},
|
||||||
},
|
},
|
||||||
Shadows: []floorShadow{
|
Shadows: []floorShadow{
|
||||||
{2, 4, 5, 33, 6, 7, 0, false, 1024},
|
{2, 4, 5, 33, 6, 7, 0, false, 1024},
|
||||||
},
|
},
|
||||||
Substitutions: []Substitution{
|
|
||||||
{1024},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exampleTile2 := Tile{
|
exampleTile2 := Tile{
|
||||||
Floors: []floorShadow{
|
Floors: []floorShadow{
|
||||||
{0, 0, 2, 3, 4, 55, 33, true, 999},
|
{9, 9, 2, 3, 4, 55, 33, true, 999},
|
||||||
|
{9, 8, 2, 3, 102, 55, 33, true, 999},
|
||||||
},
|
},
|
||||||
Walls: []Wall{
|
Walls: []Wall{
|
||||||
{2, 3, 4, 5, 3, 2, 3, 0, 33, 99},
|
{2, 3, 4, 5, 3, 2, 3, 0, 33, 99},
|
||||||
@ -250,32 +271,31 @@ func TestDS1_SetTiles(t *testing.T) {
|
|||||||
Shadows: []floorShadow{
|
Shadows: []floorShadow{
|
||||||
{2, 4, 5, 33, 6, 7, 0, false, 1024},
|
{2, 4, 5, 33, 6, 7, 0, false, 1024},
|
||||||
},
|
},
|
||||||
Substitutions: []Substitution{
|
|
||||||
{1234},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tiles := [][]Tile{{exampleTile1, exampleTile2}}
|
tiles := [][]Tile{{exampleTile1, exampleTile2}, {exampleTile2, exampleTile1}}
|
||||||
|
|
||||||
ds1.SetTiles(tiles)
|
ds1.SetTiles(tiles)
|
||||||
|
|
||||||
if ds1.tiles[0][0].Floors[0] != exampleTile1.Floors[0] {
|
test := func(ds1 *DS1) {
|
||||||
t.Fatal("unexpected tile was set")
|
if ds1.tiles[0][0].Floors[0].Prop1 != exampleTile1.Floors[0].Prop1 {
|
||||||
|
t.Fatal("1,unexpected tile was set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ds1.tiles[0][0].Walls) != len(exampleTile1.Walls) {
|
if len(ds1.tiles[0][0].Walls) != len(exampleTile1.Walls) {
|
||||||
t.Fatal("unexpected tile was set")
|
t.Fatal("2,unexpected tile was set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ds1.tiles[0][0].Walls[0] != exampleTile2.Walls[0] {
|
if ds1.tiles[0][1].Walls[0].Style != exampleTile2.Walls[0].Style {
|
||||||
t.Fatal("unexpected tile was set")
|
t.Fatal("3,unexpected tile was set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ds1.tiles[0][0].Walls) != len(exampleTile2.Walls) {
|
if len(ds1.tiles[0][0].Walls) != len(exampleTile1.Walls) {
|
||||||
t.Fatal("unexpected tile was set")
|
t.Fatal("4,unexpected tile was set")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := testIfRestorable(ds1, func(_ *DS1) {}); err != nil {
|
if err := testIfRestorable(ds1, test); err != nil {
|
||||||
t.Errorf("unable to restore: %v", err)
|
t.Errorf("unable to restore: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,28 +319,26 @@ func TestDS1_SetTile(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Walls: []Wall{
|
Walls: []Wall{
|
||||||
{2, 0, 4, 5, 3, 2, 3, 0, 33, 99},
|
{2, 0, 4, 5, 3, 2, 3, 0, 33, 99},
|
||||||
|
{5, 8, 9, 4, 3, 0, 0, 124, 221, 12},
|
||||||
},
|
},
|
||||||
Shadows: []floorShadow{
|
Shadows: []floorShadow{
|
||||||
{2, 44, 99, 2, 4, 3, 2, true, 933},
|
{2, 44, 99, 2, 4, 3, 2, true, 933},
|
||||||
},
|
},
|
||||||
Substitutions: []Substitution{
|
|
||||||
{10244},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.SetTile(0, 0, &exampleTile)
|
ds1.SetTile(0, 0, &exampleTile)
|
||||||
|
|
||||||
test := func(ds1 *DS1) {
|
test := func(ds1 *DS1) {
|
||||||
if ds1.tiles[0][0].Floors[0].Prop1 != exampleTile.Floors[0].Prop1 {
|
if ds1.tiles[0][0].Floors[0].Prop1 != exampleTile.Floors[0].Prop1 {
|
||||||
t.Fatal("c1.unexpected tile was set")
|
t.Fatal("unexpected tile was set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ds1.tiles[0][0].Walls[0].Zero != exampleTile.Walls[0].Zero {
|
if ds1.tiles[0][0].Walls[0].Zero != exampleTile.Walls[0].Zero {
|
||||||
t.Fatal("c1.unexpected tile was set")
|
t.Fatal("unexpected tile was set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ds1.tiles[0][0].Walls) != len(exampleTile.Walls) {
|
if len(ds1.tiles[0][0].Walls) != len(exampleTile.Walls) {
|
||||||
t.Fatal("c2.unexpected tile was set")
|
t.Fatal("unexpected tile was set")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,6 +489,46 @@ func TestDS1_NumberOfWalls(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDS1_SetNumberOfWalls(t *testing.T) {
|
||||||
|
ds1 := exampleDS1()
|
||||||
|
|
||||||
|
newNumber := int32(2)
|
||||||
|
|
||||||
|
ds1.SetNumberOfWallLayers(newNumber)
|
||||||
|
|
||||||
|
test := func(ds1 *DS1) {
|
||||||
|
if len(ds1.tiles[0][0].Walls) != int(newNumber) {
|
||||||
|
t.Fatal("unexpected walls length set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ds1.NumberOfWallLayers() != int(newNumber) {
|
||||||
|
t.Fatal("unexpected walls length set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := testIfRestorable(ds1, test); err != nil {
|
||||||
|
t.Errorf("unable to restore: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newNumber = 1
|
||||||
|
|
||||||
|
ds1.SetNumberOfWallLayers(newNumber)
|
||||||
|
|
||||||
|
test = func(ds1 *DS1) {
|
||||||
|
if len(ds1.tiles[0][0].Walls) != int(newNumber) {
|
||||||
|
t.Fatal("unexpected walls length set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ds1.NumberOfWallLayers() != int(newNumber) {
|
||||||
|
t.Fatal("unexpected walls length set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := testIfRestorable(ds1, test); err != nil {
|
||||||
|
t.Errorf("unable to restore: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDS1_NumberOfFloors(t *testing.T) {
|
func TestDS1_NumberOfFloors(t *testing.T) {
|
||||||
ds1 := exampleDS1()
|
ds1 := exampleDS1()
|
||||||
|
|
||||||
@ -479,6 +537,46 @@ func TestDS1_NumberOfFloors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDS1_SetNumberOfFloors(t *testing.T) {
|
||||||
|
ds1 := exampleDS1()
|
||||||
|
|
||||||
|
newNumber := int32(2)
|
||||||
|
|
||||||
|
ds1.SetNumberOfFloorLayers(newNumber)
|
||||||
|
|
||||||
|
test := func(ds1 *DS1) {
|
||||||
|
if len(ds1.tiles[0][0].Floors) != int(newNumber) {
|
||||||
|
t.Fatal("unexpected floors length set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ds1.numberOfFloorLayers != newNumber {
|
||||||
|
t.Fatal("unexpected floors length set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := testIfRestorable(ds1, test); err != nil {
|
||||||
|
t.Errorf("unable to restore: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newNumber = 1
|
||||||
|
|
||||||
|
ds1.SetNumberOfFloorLayers(newNumber)
|
||||||
|
|
||||||
|
test = func(ds1 *DS1) {
|
||||||
|
if len(ds1.tiles[0][0].Floors) != int(newNumber) {
|
||||||
|
t.Fatal("unexpected floors length set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ds1.numberOfFloorLayers != newNumber {
|
||||||
|
t.Fatal("unexpected floors length set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := testIfRestorable(ds1, test); err != nil {
|
||||||
|
t.Errorf("unable to restore: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDS1_NumberOfShadowLayers(t *testing.T) {
|
func TestDS1_NumberOfShadowLayers(t *testing.T) {
|
||||||
ds1 := exampleDS1()
|
ds1 := exampleDS1()
|
||||||
|
|
||||||
@ -526,3 +624,27 @@ func TestDS1_SetSubstitutionGroups(t *testing.T) {
|
|||||||
t.Fatal("unexpected substitution group added")
|
t.Fatal("unexpected substitution group added")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDS1_setupStreamLayerTypes(t *testing.T) {
|
||||||
|
ds1 := exampleDS1()
|
||||||
|
|
||||||
|
lst := []d2enum.LayerStreamType{
|
||||||
|
d2enum.LayerStreamWall1,
|
||||||
|
d2enum.LayerStreamOrientation1,
|
||||||
|
d2enum.LayerStreamFloor1,
|
||||||
|
d2enum.LayerStreamShadow,
|
||||||
|
d2enum.LayerStreamSubstitute,
|
||||||
|
}
|
||||||
|
|
||||||
|
layerStreamTypes := ds1.setupStreamLayerTypes()
|
||||||
|
|
||||||
|
if len(lst) != len(layerStreamTypes) {
|
||||||
|
t.Fatal("unexpected length")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range lst {
|
||||||
|
if lst[i] != layerStreamTypes[i] {
|
||||||
|
t.Fatal("Unexpected type was set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user