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:
gucio321 2021-02-22 21:18:35 +01:00 committed by Dylan Knuth
parent ca47018e8a
commit 5706a1c19a
2 changed files with 300 additions and 107 deletions

View File

@ -56,11 +56,10 @@ type DS1 struct {
numberOfSubstitutionLayers int32 // SubstitutionNum number of substitution layer used
// substitutionGroupsNum int32 // SubstitutionGroupsNum number of substitution groups, datas between objects & NPC paths
dirty bool // when modifying tiles, need to perform upkeep on ds1 state
unknown1 []byte
layerStreamTypes []d2enum.LayerStreamType
unknown2 uint32
npcIndexes []int
dirty bool // when modifying tiles, need to perform upkeep on ds1 state
unknown1 []byte
unknown2 uint32
npcIndexes []int
}
// Files returns a list of file path strings.
@ -135,7 +134,6 @@ func (ds1 *DS1) SetTiles(tiles [][]Tile) {
}
ds1.tiles = tiles
ds1.layerStreamTypes = ds1.setupStreamLayerTypes()
ds1.dirty = true
ds1.update()
}
@ -165,6 +163,7 @@ func (ds1 *DS1) SetTile(x, y int, t *Tile) {
ds1.tiles[y][x] = *t
ds1.dirty = true
ds1.update()
}
// Version returns the ds1's version
@ -283,8 +282,8 @@ func (ds1 *DS1) Size() (w, h int) {
return int(ds1.width), int(ds1.height)
}
// setSize force sets the ds1's size (width,height)
func (ds1 *DS1) setSize(w, h int) {
// SetSize force sets the ds1's size (width,height)
func (ds1 *DS1) SetSize(w, h int) {
ds1.SetWidth(w)
ds1.SetHeight(h)
ds1.width, ds1.height = int32(w), int32(h)
@ -323,6 +322,38 @@ func (ds1 *DS1) NumberOfWallLayers() int {
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
func (ds1 *DS1) NumberOfFloorLayers() int {
if ds1.dirty {
@ -332,6 +363,41 @@ func (ds1 *DS1) NumberOfFloorLayers() int {
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
func (ds1 *DS1) NumberOfShadowLayers() int {
if ds1.dirty {
@ -365,7 +431,18 @@ func (ds1 *DS1) update() {
ds1.enforceAllTileLayersMatch()
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
}
@ -405,35 +482,33 @@ func LoadDS1(fileData []byte) (*DS1, error) {
err = ds1.loadHeader(br)
if err != nil {
return nil, err
return nil, fmt.Errorf("loading header: %v", err)
}
if ds1.version >= v9 && ds1.version <= v13 {
// Skipping two dwords because they are "meaningless"?
ds1.unknown1, err = br.ReadBytes(unknown1BytesCount)
if err != nil {
return nil, err
return nil, fmt.Errorf("reading unknown1: %v", err)
}
}
if ds1.version >= v4 {
ds1.numberOfWallLayers, err = br.ReadInt32()
if err != nil {
return nil, err
return nil, fmt.Errorf("reading wall number: %v", err)
}
if ds1.version >= v16 {
ds1.numberOfFloorLayers, err = br.ReadInt32()
if err != nil {
return nil, err
return nil, fmt.Errorf("reading number of floors: %v", err)
}
} else {
ds1.numberOfFloorLayers = 1
}
}
ds1.layerStreamTypes = ds1.setupStreamLayerTypes()
ds1.tiles = make([][]Tile, ds1.height)
for y := range ds1.tiles {
@ -448,22 +523,22 @@ func LoadDS1(fileData []byte) (*DS1, error) {
err = ds1.loadLayerStreams(br)
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 {
return nil, err
return nil, fmt.Errorf("loading objects: %v", err)
}
err = ds1.loadSubstitutions(br)
if err != nil {
return nil, err
return nil, fmt.Errorf("loading substitutions: %v", err)
}
err = ds1.loadNPCs(br)
if err != nil {
return nil, err
return nil, fmt.Errorf("loading npc's: %v", err)
}
return ds1, nil
@ -474,17 +549,17 @@ func (ds1 *DS1) loadHeader(br *d2datautils.StreamReader) error {
ds1.version, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading version: %v", err)
}
ds1.width, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading width: %v", err)
}
ds1.height, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading height: %v", err)
}
ds1.width++
@ -493,7 +568,7 @@ func (ds1 *DS1) loadHeader(br *d2datautils.StreamReader) error {
if ds1.version >= v8 {
ds1.act, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading act: %v", err)
}
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 {
ds1.substitutionType, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading substitution type: %v", err)
}
if ds1.substitutionType == 1 || ds1.substitutionType == 2 {
@ -512,7 +587,7 @@ func (ds1 *DS1) loadHeader(br *d2datautils.StreamReader) error {
err = ds1.loadFileList(br)
if err != nil {
return err
return fmt.Errorf("loading file list: %v", err)
}
return nil
@ -523,7 +598,7 @@ func (ds1 *DS1) loadFileList(br *d2datautils.StreamReader) error {
// These files reference things that don't exist anymore :-?
numberOfFiles, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading number of files: %v", err)
}
ds1.files = make([]string, numberOfFiles)
@ -534,7 +609,7 @@ func (ds1 *DS1) loadFileList(br *d2datautils.StreamReader) error {
for {
ch, err := br.ReadByte()
if err != nil {
return err
return fmt.Errorf("reading file character: %v", err)
}
if ch == 0 {
@ -549,13 +624,13 @@ func (ds1 *DS1) loadFileList(br *d2datautils.StreamReader) error {
return nil
}
func (ds1 *DS1) loadobjects(br *d2datautils.StreamReader) error {
func (ds1 *DS1) loadObjects(br *d2datautils.StreamReader) error {
if ds1.version < v2 {
ds1.objects = make([]Object, 0)
} else {
numberOfobjects, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading number of objects: %v", err)
}
ds1.objects = make([]Object, numberOfobjects)
@ -564,27 +639,27 @@ func (ds1 *DS1) loadobjects(br *d2datautils.StreamReader) error {
obj := Object{}
objType, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading object's %d type: %v", objIdx, err)
}
objID, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading object's %d ID: %v", objIdx, err)
}
objX, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading object's %d X: %v", objIdx, err)
}
objY, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading object's %d Y: %v", objY, err)
}
objFlags, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading object's %d flags: %v", objIdx, err)
}
obj.Type = int(objType)
@ -613,13 +688,13 @@ func (ds1 *DS1) loadSubstitutions(br *d2datautils.StreamReader) error {
if ds1.version >= v18 {
ds1.unknown2, err = br.ReadUInt32()
if err != nil {
return err
return fmt.Errorf("reading unknown 2: %v", err)
}
}
numberOfSubGroups, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading number of sub groups: %v", err)
}
ds1.substitutionGroups = make([]SubstitutionGroup, numberOfSubGroups)
@ -629,27 +704,27 @@ func (ds1 *DS1) loadSubstitutions(br *d2datautils.StreamReader) error {
newSub.TileX, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading substitution's %d X: %v", subIdx, err)
}
newSub.TileY, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading substitution's %d Y: %v", subIdx, err)
}
newSub.WidthInTiles, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading substitution's %d W: %v", subIdx, err)
}
newSub.HeightInTiles, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading substitution's %d H: %v", subIdx, err)
}
newSub.Unknown, err = br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading substitution's %d unknown: %v", subIdx, err)
}
ds1.substitutionGroups[subIdx] = newSub
@ -700,28 +775,28 @@ func (ds1 *DS1) loadNPCs(br *d2datautils.StreamReader) error {
var err error
if ds1.version < v14 {
return err
return nil
}
numberOfNpcs, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading number of npcs: %v", err)
}
for npcIdx := 0; npcIdx < int(numberOfNpcs); npcIdx++ {
numPaths, err := br.ReadInt32() // nolint:govet // I want to re-use this error variable
if err != nil {
return err
return fmt.Errorf("reading number of paths for npc %d: %v", npcIdx, err)
}
npcX, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading X pos for NPC %d: %v", npcIdx, err)
}
npcY, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading Y pos for NPC %d: %v", npcIdx, err)
}
objIdx := -1
@ -738,7 +813,7 @@ func (ds1 *DS1) loadNPCs(br *d2datautils.StreamReader) error {
if objIdx > -1 {
err = ds1.loadNpcPaths(br, objIdx, int(numPaths))
if err != nil {
return err
return fmt.Errorf("loading paths for NPC %d: %v", npcIdx, err)
}
} else {
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 {
var err error
if ds1.objects[objIdx].Paths == nil {
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...
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...
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))
@ -777,7 +850,7 @@ func (ds1 *DS1) loadNpcPaths(br *d2datautils.StreamReader, objIdx, numPaths int)
if ds1.version >= v15 {
action, err := br.ReadInt32()
if err != nil {
return err
return fmt.Errorf("reading action for path %d: %v", pathIdx, err)
}
newPath.Action = int(action)
@ -786,26 +859,24 @@ func (ds1 *DS1) loadNpcPaths(br *d2datautils.StreamReader, objIdx, numPaths int)
ds1.objects[objIdx].Paths[pathIdx] = newPath
}
return err
return nil
}
func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error {
var err error
var dirLookup = []int32{
0x00, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, 0x05, 0x05, 0x06,
0x06, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x10, 0x11, 0x12, 0x14,
}
for lIdx := range ds1.layerStreamTypes {
layerStreamType := ds1.layerStreamTypes[lIdx]
layerStreamTypes := ds1.setupStreamLayerTypes()
for _, layerStreamType := range layerStreamTypes {
for y := 0; y < int(ds1.height); y++ {
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 {
return err
return fmt.Errorf("reading layer's dword: %v", err)
}
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
@ -919,9 +990,9 @@ func (ds1 *DS1) Marshal() []byte {
}
func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) {
for lIdx := range ds1.layerStreamTypes {
layerStreamType := ds1.layerStreamTypes[lIdx]
layerStreamTypes := ds1.setupStreamLayerTypes()
for _, layerStreamType := range layerStreamTypes {
for y := 0; y < int(ds1.height); y++ {
for x := 0; x < int(ds1.width); x++ {
dw := uint32(0)

View File

@ -4,6 +4,7 @@ import (
"testing"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2path"
)
func exampleDS1() *DS1 {
@ -11,18 +12,38 @@ func exampleDS1() *DS1 {
files: []string{"a.dt1", "b.dt1"},
objects: []Object{
{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, 3, 0, 0, 0, nil},
},
tiles: [][]Tile{ // 2x2
{
Tile{[]Floor{{}}, []Wall{{}}, []Shadow{{}}, []Substitution{}},
Tile{[]Floor{{}}, []Wall{{}}, []Shadow{{}}, []Substitution{}},
Tile{
[]Floor{{}},
[]Wall{{}},
[]Shadow{{}},
[]Substitution{{}},
},
Tile{
[]Floor{{}},
[]Wall{{}},
[]Shadow{{}},
[]Substitution{{}},
},
},
{
Tile{[]Floor{{}}, []Wall{{}}, []Shadow{{}}, []Substitution{}},
Tile{[]Floor{{}}, []Wall{{}}, []Shadow{{}}, []Substitution{}},
Tile{
[]Floor{{}},
[]Wall{{}},
[]Shadow{{}},
[]Substitution{{}},
},
Tile{
[]Floor{{}},
[]Wall{{}},
[]Shadow{{}},
[]Substitution{{}},
},
},
},
substitutionGroups: nil,
@ -35,13 +56,7 @@ func exampleDS1() *DS1 {
numberOfFloorLayers: 1,
numberOfShadowLayers: 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
data := ds1.Marshal()
newDS1, err := LoadDS1(data)
_ = newDS1
if err != nil {
return err
}
test(newDS1)
return err
return nil
}
func TestDS1_Marshal(t *testing.T) {
@ -74,6 +92,10 @@ func TestDS1_Marshal(t *testing.T) {
if b.width != a.width {
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) {
@ -227,22 +249,21 @@ func TestDS1_SetTiles(t *testing.T) {
exampleTile1 := Tile{
Floors: []floorShadow{
{0, 0, 2, 3, 4, 55, 33, true, 999},
{8, 7, 2, 3, 4, 55, 33, true, 999},
},
Walls: []Wall{
{2, 3, 4, 5, 3, 2, 3, 0, 33, 99},
{2, 3, 4, 5, 3, 2, 3, 0, 33, 99},
},
Shadows: []floorShadow{
{2, 4, 5, 33, 6, 7, 0, false, 1024},
},
Substitutions: []Substitution{
{1024},
},
}
exampleTile2 := Tile{
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{
{2, 3, 4, 5, 3, 2, 3, 0, 33, 99},
@ -250,32 +271,31 @@ func TestDS1_SetTiles(t *testing.T) {
Shadows: []floorShadow{
{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)
if ds1.tiles[0][0].Floors[0] != exampleTile1.Floors[0] {
t.Fatal("unexpected tile was set")
test := func(ds1 *DS1) {
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) {
t.Fatal("2,unexpected tile was set")
}
if ds1.tiles[0][1].Walls[0].Style != exampleTile2.Walls[0].Style {
t.Fatal("3,unexpected tile was set")
}
if len(ds1.tiles[0][0].Walls) != len(exampleTile1.Walls) {
t.Fatal("4,unexpected tile was set")
}
}
if len(ds1.tiles[0][0].Walls) != len(exampleTile1.Walls) {
t.Fatal("unexpected tile was set")
}
if ds1.tiles[0][0].Walls[0] != exampleTile2.Walls[0] {
t.Fatal("unexpected tile was set")
}
if len(ds1.tiles[0][0].Walls) != len(exampleTile2.Walls) {
t.Fatal("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)
}
}
@ -299,28 +319,26 @@ func TestDS1_SetTile(t *testing.T) {
},
Walls: []Wall{
{2, 0, 4, 5, 3, 2, 3, 0, 33, 99},
{5, 8, 9, 4, 3, 0, 0, 124, 221, 12},
},
Shadows: []floorShadow{
{2, 44, 99, 2, 4, 3, 2, true, 933},
},
Substitutions: []Substitution{
{10244},
},
}
ds1.SetTile(0, 0, &exampleTile)
test := func(ds1 *DS1) {
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 {
t.Fatal("c1.unexpected tile was set")
t.Fatal("unexpected tile was set")
}
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) {
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) {
ds1 := exampleDS1()
@ -526,3 +624,27 @@ func TestDS1_SetSubstitutionGroups(t *testing.T) {
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")
}
}
}