Skip to content
This repository has been archived by the owner on Dec 20, 2021. It is now read-only.

Commit

Permalink
Refactoring d2ds1
Browse files Browse the repository at this point in the history
* Adding setters/getters so that state management can be maintained
internally when the ds1 struct is altered
* Adding unit tests for DS1
  • Loading branch information
gravestench authored and dknuth-tti committed Mar 24, 2021
1 parent ecab467 commit 5e0e51d
Show file tree
Hide file tree
Showing 11 changed files with 781 additions and 154 deletions.
573 changes: 443 additions & 130 deletions d2common/d2fileformats/d2ds1/ds1.go

Large diffs are not rendered by default.

289 changes: 289 additions & 0 deletions d2common/d2fileformats/d2ds1/ds1_test.go
@@ -0,0 +1,289 @@
package d2ds1

import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"testing"
)

func exampleDS1() *DS1 {
return &DS1{
files: []string{"a.dt1", "b.dt1"},
objects: []Object{
{0, 0, 0, 0, 0, nil},
{0, 1, 0, 0, 0, nil},
{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{}},
},
},
substitutionGroups: nil,
version: 17,
width: 2,
height: 2,
act: 1,
substitutionType: 0,
numberOfWallLayers: 1,
numberOfFloorLayers: 1,
numberOfShadowLayers: 1,
numberOfSubstitutionLayers: 1,
layerStreamTypes: []d2enum.LayerStreamType{
d2enum.LayerStreamWall1,
d2enum.LayerStreamOrientation1,
d2enum.LayerStreamFloor1,
d2enum.LayerStreamShadow,
},
npcIndexes: []int{},
}
}

func TestDS1_Act(t *testing.T) {
ds1 := exampleDS1()

if ds1.Act() != int(ds1.act) {
t.Error("unexpected value in example ds1")
}
}

func TestDS1_AddFile(t *testing.T) {
ds1 := exampleDS1()

numBefore := len(ds1.files)

ds1.AddFile("other.ds1")

numAfter := len(ds1.files)

if (numBefore+1) != numAfter {
t.Error("unexpected number of files in ds1")
}
}

func TestDS1_AddObject(t *testing.T) {
ds1 := exampleDS1()

numBefore := len(ds1.objects)

ds1.AddObject(Object{})

numAfter := len(ds1.objects)

if (numBefore+1) != numAfter {
t.Error("unexpected number of objects in ds1")
}
}

func TestDS1_Files(t *testing.T) {
ds1 := exampleDS1()

files := ds1.Files()

for idx := range files {
if ds1.files[idx] != files[idx] {
t.Error("unexpected files from ds1")
}
}
}

func TestDS1_Height(t *testing.T) {
ds1 := exampleDS1()

if int(ds1.height) != ds1.Height(){
t.Error("unexpected height")
}
}

func TestDS1_Marshal(t *testing.T) {
a := exampleDS1()

bytes := a.Marshal()

b, err := LoadDS1(bytes)
if err != nil {
t.Error("could not load new ds1 from marshalled ds1 data")
return
}

if b.width != a.width {
t.Error("new ds1 does not match original")
}
}

func TestDS1_NumberOfFloors(t *testing.T) {
ds1 := exampleDS1()

if ds1.NumberOfFloorLayers() != int(ds1.numberOfFloorLayers) {
t.Error("unexpected number of floor layers")
}
}

func TestDS1_NumberOfShadowLayers(t *testing.T) {
ds1 := exampleDS1()

if ds1.NumberOfShadowLayers() != int(ds1.numberOfShadowLayers) {
t.Error("unexpected number of shadow layers")
}
}

func TestDS1_NumberOfSubstitutionLayers(t *testing.T) {
ds1 := exampleDS1()

if ds1.NumberOfSubstitutionLayers() != int(ds1.numberOfSubstitutionLayers) {
t.Error("unexpected number of substitution layers")
}
}

func TestDS1_NumberOfWalls(t *testing.T) {
ds1 := exampleDS1()

if ds1.NumberOfWallLayers() != int(ds1.numberOfWallLayers) {
t.Error("unexpected number of wall layers")
}
}

func TestDS1_Objects(t *testing.T) {
ds1 := exampleDS1()

objects := ds1.Objects()

for idx := range ds1.objects {
if !ds1.objects[idx].Equals(&objects[idx]) {
t.Error("unexpected object")
}
}
}

func TestDS1_RemoveFile(t *testing.T) {
ds1 := exampleDS1()

numBefore := len(ds1.files)

ds1.RemoveFile("nonexistant file")

if len(ds1.files) != numBefore {
t.Error("file removed when it should not have been")
}

filename := "c.ds1"

ds1.AddFile(filename)

if len(ds1.files) == numBefore {
t.Error("file not added when it should have been")
}

ds1.RemoveFile(filename)

if len(ds1.files) != numBefore {
t.Error("file not removed when it should have been")
}
}

func TestDS1_RemoveObject(t *testing.T) {
ds1 := exampleDS1()

nice := 69420

obj := Object{
ID: nice,
}

ds1.AddObject(obj)

numBefore := len(ds1.objects)

ds1.RemoveObject(obj)

if len(ds1.objects) == numBefore {
t.Error("did not remove object when expected")
}
}

func TestDS1_SetAct(t *testing.T) {
ds1 := exampleDS1()

ds1.SetAct(-1)

if ds1.Act() < 0 {
t.Error("act cannot be less than 0")
}

nice := 69420

ds1.SetAct(nice)

if int(ds1.act) != nice {
t.Error("unexpected value for act")
}
}

func TestDS1_SetHeight(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SetSize(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SetSubstitutionGroups(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SetSubstitutionType(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SetTile(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SetTiles(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SetVersion(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SetWidth(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_Size(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SubstitutionGroups(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_SubstitutionType(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_Tile(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_Tiles(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_Version(t *testing.T) {
//ds1 := exampleDS1()
}

func TestDS1_Width(t *testing.T) {
//ds1 := exampleDS1()
}

func TestLoadDS1(t *testing.T) {
//ds1 := exampleDS1()
}
16 changes: 11 additions & 5 deletions d2common/d2fileformats/d2ds1/floor_shadow_record.go
Expand Up @@ -30,8 +30,8 @@ const (
hiddenLength = 1
)

// FloorShadowRecord represents a floor or shadow record in a DS1 file.
type FloorShadowRecord struct {
// FloorShadow represents a floor or shadow record in a DS1 file (they share a common struct).
type FloorShadow struct {
Prop1 byte
Sequence byte
Unknown1 byte
Expand All @@ -43,13 +43,19 @@ type FloorShadowRecord struct {
YAdjust int
}

// Floor represents a floor record in a DS1 file. (it is just an alias of FloorShadow).
type Floor = FloorShadow

// Shadow represents a shadow record in a DS1 file. (it is just an alias of FloorShadow).
type Shadow = FloorShadow

// Hidden returns if floor/shadow is hidden
func (f *FloorShadowRecord) Hidden() bool {
func (f *Floor) Hidden() bool {
return f.HiddenBytes > 0
}

// Decode decodes floor-shadow record
func (f *FloorShadowRecord) Decode(dw uint32) {
func (f *Floor) Decode(dw uint32) {
f.Prop1 = byte((dw & prop1Bitmask) >> prop1Offset)
f.Sequence = byte((dw & sequenceBitmask) >> sequenceOffset)
f.Unknown1 = byte((dw & unknown1Bitmask) >> unknown1Offset)
Expand All @@ -59,7 +65,7 @@ func (f *FloorShadowRecord) Decode(dw uint32) {
}

// Encode adds Floor's bits to stream writter given
func (f *FloorShadowRecord) Encode(sw *d2datautils.StreamWriter) {
func (f *Floor) Encode(sw *d2datautils.StreamWriter) {
sw.PushBits32(uint32(f.Prop1), prop1Length)
sw.PushBits32(uint32(f.Sequence), sequenceLength)
sw.PushBits32(uint32(f.Unknown1), unknown1Length)
Expand Down
10 changes: 10 additions & 0 deletions d2common/d2fileformats/d2ds1/object.go
Expand Up @@ -13,3 +13,13 @@ type Object struct {
Flags int
Paths []d2path.Path
}

// Equals checks if this Object is equivalent to the given Object
func (o *Object) Equals(other *Object) bool {
return o.Type == other.Type &&
o.ID == other.ID &&
o.X == other.X &&
o.Y == other.Y &&
o.Flags == other.Flags &&
len(o.Paths) == len(other.Paths)
}
4 changes: 2 additions & 2 deletions d2common/d2fileformats/d2ds1/substitution_record.go
@@ -1,6 +1,6 @@
package d2ds1

// SubstitutionRecord represents a substitution record in a DS1 file.
type SubstitutionRecord struct {
// Substitution represents a substitution record in a DS1 file.
type Substitution struct {
Unknown uint32
}
21 changes: 15 additions & 6 deletions d2common/d2fileformats/d2ds1/tile_record.go
@@ -1,9 +1,18 @@
package d2ds1

// TileRecord represents a tile record in a DS1 file.
type TileRecord struct {
Floors []FloorShadowRecord // Collection of floor records
Walls []WallRecord // Collection of wall records
Shadows []FloorShadowRecord // Collection of shadow records
Substitutions []SubstitutionRecord // Collection of substitutions
// Tile represents a tile record in a DS1 file.
type Tile struct {
Floors []Floor // Collection of floor records
Walls []Wall // Collection of wall records
Shadows []Shadow // Collection of shadow records
Substitutions []Substitution // Collection of substitutions
}

func makeDefaultTile() Tile {
return Tile{
Floors: []Floor{{}},
Walls: []Wall{{}},
Shadows: []Shadow{{}},
Substitutions: []Substitution{{}},
}
}

0 comments on commit 5e0e51d

Please sign in to comment.