Ds1 refactor (#11)

* Refactoring d2ds1

* Adding setters/getters so that state management can be maintained
internally when the ds1 struct is altered
* Adding unit tests for DS1

* unit tests for ds1 (#4)

* ds1 refactor: added test fore some methods; put tests in right order

* ds1 refactor: unit tests for all methods

* ds1 refactor: fixed build errors

* ds1 refactor: lintfix

* ds1 refactor: fixed bug with SetWidth, SetHeight methods

* ds1 refactor: rename tile_record.go -> tile.go

* ds1 refactor: unit test for SetTiles

Co-authored-by: M. Sz <mszeptuch@protonmail.com>

* renamed some files in d2ds1

* d2ds1.FloorShadow is now private

* renamed another file

* DS1.Tile() now calls update if dirty

* Ds1 refactor: some test improvement (#5)

* ds1 refactor: floor_shadow.go: methods Encode, Decode an Hidden are methods of floorShadow

* ds1 refactor: test checks, if our methods sets all fields correctly

* ds1 refactor: minor bugfixes

* i don't remember what's this, but i commit it ;-)

* ds1 refactor: reverted some pushed by mistake things

Co-authored-by: M. Sz <mszeptuch@protonmail.com>

* 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>

* Ds1 refactor: removed npcIndexes field+fixed SetNumberOfWalls bug (#7)

* ds1 refactor: removed npcIndexes field
it was unnecessary, because described a number of objects with paths to use in encoder, but we can calculate manually

* ds1 refactor: fixed set number of (layers) bug

* ds1 refactor: SetNumberOf...Layers now returns error if incorrect number given

* ds1 refactor: lintfix

* ds1 refactor: rename: setupStreamLayerTypes -> GetStreamLayerTypes

Co-authored-by: M. Sz <mszeptuch@protonmail.com>

* WIP

* Ds1 refactor - tests (#10)

* ds1 refactor test: example data

* added loader check

* ds1 refactor: fixed bug, with loading substitutions; added descriptive error message in engine.go:118 and changed Logger.Error with Logger.Fatal

* ds1 refactor: fixed loading bug

* ds1 refactor: fixed bug when walls wasn't rendered (now we can see only walls :-)

Co-authored-by: M. Sz <mszeptuch@protonmail.com>

* ds1: floor rendering bugfix

* ds1: implemented encode layers method

* ds1: implemented encoder

* ds1: update of ds1_test

Co-authored-by: gravestench <dknuth0101@gmail.com>
Co-authored-by: M. Sz <mszeptuch@protonmail.com>
This commit is contained in:
gucio321 2021-03-24 18:28:02 +01:00 committed by GitHub
parent 6f41387e30
commit 6e7e7b9d3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 149 additions and 175 deletions

View File

@ -475,7 +475,7 @@ func (ds1 *DS1) loadNpcPaths(br *d2datautils.StreamReader, objIdx, numPaths int)
} }
func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error { func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error {
var dirLookup = []int32{ 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,
@ -513,9 +513,9 @@ func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error {
floorIndex := int(layerStreamType) - int(layerStreamFloor1) floorIndex := int(layerStreamType) - int(layerStreamFloor1)
ds1.Floors[floorIndex].Tile(x, y).DecodeFloor(dw) ds1.Floors[floorIndex].Tile(x, y).DecodeFloor(dw)
case layerStreamShadow1: case layerStreamShadow1:
ds1.Floors[0].Tile(x, y).DecodeShadow(dw) ds1.Shadows[0].Tile(x, y).DecodeShadow(dw)
case layerStreamSubstitute1: case layerStreamSubstitute1:
ds1.Floors[0].Tile(x, y).Substitution = dw ds1.Substitutions[0].Tile(x, y).Substitution = dw
} }
} }
} }
@ -529,145 +529,144 @@ func (ds1 *DS1) SetSize(w, h int) {
ds1.ds1Layers.SetSize(w, h) ds1.ds1Layers.SetSize(w, h)
} }
// // Marshal encodes ds1 back to byte slice
// // Marshal encodes ds1 back to byte slice func (ds1 *DS1) Marshal() []byte {
// func (ds1 *DS1) Marshal() []byte { // create stream writer
// // create stream writer sw := d2datautils.CreateStreamWriter()
// sw := d2datautils.CreateStreamWriter()
// // Step 1 - encode header
// // Step 1 - encode header sw.PushInt32(int32(ds1.version))
// sw.PushInt32(ds1.version) sw.PushInt32(int32(ds1.width - 1))
// sw.PushInt32(ds1.width - 1) sw.PushInt32(int32(ds1.height - 1))
// sw.PushInt32(ds1.height - 1)
// if ds1.version.specifiesAct() {
// if ds1.version >= v8 { sw.PushInt32(ds1.Act - 1)
// sw.PushInt32(ds1.Act - 1) }
// }
// if ds1.version.specifiesSubstitutionType() {
// if ds1.version >= v10 { sw.PushInt32(ds1.substitutionType)
// sw.PushInt32(ds1.substitutionType) }
// }
// if ds1.version.hasFileList() {
// if ds1.version >= v3 { sw.PushInt32(int32(len(ds1.Files)))
// sw.PushInt32(int32(len(ds1.Files)))
// for _, i := range ds1.Files {
// for _, i := range ds1.Files { sw.PushBytes([]byte(i)...)
// sw.PushBytes([]byte(i)...)
// // separator
// // separator sw.PushBytes(0)
// sw.PushBytes(0) }
// } }
// }
// if ds1.version.hasUnknown1Bytes() {
// if ds1.version >= v9 && ds1.version <= v13 { sw.PushBytes(ds1.unknown1...)
// sw.PushBytes(ds1.unknown1...) }
// }
// if ds1.version.specifiesWalls() {
// if ds1.version >= v4 { sw.PushInt32(int32(len(ds1.Walls)))
// sw.PushInt32(ds1.numberOfWallLayers)
// if ds1.version.specifiesFloors() {
// if ds1.version >= v16 { sw.PushInt32(int32(len(ds1.Walls)))
// sw.PushInt32(ds1.numberOfFloorLayers) }
// } }
// }
// // Step 2 - encode grid
// // Step 2 - encode grid ds1.encodeLayers(sw)
// ds1.encodeLayers(sw)
// // Step 3 - encode Objects
// // Step 3 - encode Objects if ds1.version.hasObjects() {
// if !(ds1.version < v2) { sw.PushInt32(int32(len(ds1.Objects)))
// sw.PushInt32(int32(len(ds1.Objects)))
// for _, i := range ds1.Objects {
// for _, i := range ds1.Objects { sw.PushUint32(uint32(i.Type))
// sw.PushUint32(uint32(i.Type)) sw.PushUint32(uint32(i.ID))
// sw.PushUint32(uint32(i.ID)) sw.PushUint32(uint32(i.X))
// sw.PushUint32(uint32(i.X)) sw.PushUint32(uint32(i.Y))
// sw.PushUint32(uint32(i.Y)) sw.PushUint32(uint32(i.Flags))
// sw.PushUint32(uint32(i.Flags)) }
// } }
// }
// // Step 4 - encode Substitutions
// // Step 4 - encode Substitutions hasSubstitutions := ds1.version.hasSubstitutions() &&
// if ds1.version >= v12 && (ds1.substitutionType == subType1 || ds1.substitutionType == subType2) { (ds1.substitutionType == subType1 || ds1.substitutionType == subType2)
// sw.PushUint32(ds1.unknown2)
// if hasSubstitutions {
// sw.PushUint32(uint32(len(ds1.substitutionGroups))) sw.PushUint32(ds1.unknown2)
//
// for _, i := range ds1.substitutionGroups { sw.PushUint32(uint32(len(ds1.substitutionGroups)))
// sw.PushInt32(i.TileX)
// sw.PushInt32(i.TileY) for _, i := range ds1.substitutionGroups {
// sw.PushInt32(i.WidthInTiles) sw.PushInt32(i.TileX)
// sw.PushInt32(i.HeightInTiles) sw.PushInt32(i.TileY)
// sw.PushInt32(i.Unknown) sw.PushInt32(i.WidthInTiles)
// } sw.PushInt32(i.HeightInTiles)
// } sw.PushInt32(i.Unknown)
// }
// // Step 5 - encode NPC's and its paths }
// ds1.encodeNPCs(sw)
// // Step 5 - encode NPC's and its paths
// return sw.GetBytes() ds1.encodeNPCs(sw)
// }
// return sw.GetBytes()
// func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) { }
// /*
// layerStreamTypes := ds1.getLayerSchema() func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) {
// layerStreamTypes := ds1.getLayerSchema()
// for _, layerStreamType := range layerStreamTypes {
// for y := 0; y < int(ds1.height); y++ { for _, layerStreamType := range layerStreamTypes {
// for x := 0; x < int(ds1.width); x++ { for y := 0; y < int(ds1.height); y++ {
// dw := uint32(0) for x := 0; x < int(ds1.width); x++ {
// dw := uint32(0)
// switch layerStreamType {
// case layerStreamWall1, layerStreamWall2, layerStreamWall3, layerStreamWall4: switch layerStreamType {
// wallIndex := int(layerStreamType) - int(layerStreamWall1) case layerStreamWall1, layerStreamWall2, layerStreamWall3, layerStreamWall4:
// ds1.tiles[y][x].Walls[wallIndex].Encode(sw) wallIndex := int(layerStreamType) - int(layerStreamWall1)
// case layerStreamOrientation1, layerStreamOrientation2, ds1.Walls[wallIndex].Tile(x, y).EncodeWall(sw)
// layerStreamOrientation3, layerStreamOrientation4: case layerStreamOrientation1, layerStreamOrientation2,
// wallIndex := int(layerStreamType) - int(layerStreamOrientation1) layerStreamOrientation3, layerStreamOrientation4:
// dw |= uint32(ds1.tiles[y][x].Walls[wallIndex].Type) wallIndex := int(layerStreamType) - int(layerStreamOrientation1)
// dw |= (uint32(ds1.tiles[y][x].Walls[wallIndex].Zero) & wallZeroBitmask) << wallZeroOffset dw |= uint32(ds1.Walls[wallIndex].Tile(x, y).Type)
// dw |= (uint32(ds1.Walls[wallIndex].Tile(x, y).Zero) & wallZeroBitmask) << wallZeroOffset
// sw.PushUint32(dw)
// case layerStreamFloor1, layerStreamFloor2: sw.PushUint32(dw)
// floorIndex := int(layerStreamType) - int(layerStreamFloor1) case layerStreamFloor1, layerStreamFloor2:
// ds1.tiles[y][x].Floors[floorIndex].Encode(sw) floorIndex := int(layerStreamType) - int(layerStreamFloor1)
// case d2enum.layerStreamShadow1: ds1.Floors[floorIndex].Tile(x, y).EncodeFloor(sw)
// ds1.tiles[y][x].Shadows[0].Encode(sw) case layerStreamShadow1:
// case d2enum.layerStreamSubstitute1: ds1.Shadows[0].Tile(x, y).EncodeShadow(sw)
// sw.PushUint32(ds1.tiles[y][x].Substitutions[0].Unknown) case layerStreamSubstitute1:
// } sw.PushUint32(ds1.Substitutions[0].Tile(x, y).Substitution)
// } }
// } }
// } }
// */ }
// } }
//
// func (ds1 *DS1) encodeNPCs(sw *d2datautils.StreamWriter) { func (ds1 *DS1) encodeNPCs(sw *d2datautils.StreamWriter) {
// objectsWithPaths := make([]int, 0) objectsWithPaths := make([]int, 0)
//
// for n, obj := range ds1.Objects { for n, obj := range ds1.Objects {
// if len(obj.Paths) != 0 { if len(obj.Paths) != 0 {
// objectsWithPaths = append(objectsWithPaths, n) objectsWithPaths = append(objectsWithPaths, n)
// } }
// } }
//
// // Step 5.1 - encode npc's // Step 5.1 - encode npc's
// sw.PushUint32(uint32(len(objectsWithPaths))) sw.PushUint32(uint32(len(objectsWithPaths)))
//
// // Step 5.2 - enoce npcs' paths // Step 5.2 - enoce npcs' paths
// for objectIdx := range objectsWithPaths { for objectIdx := range objectsWithPaths {
// sw.PushUint32(uint32(len(ds1.Objects[objectIdx].Paths))) sw.PushUint32(uint32(len(ds1.Objects[objectIdx].Paths)))
// sw.PushUint32(uint32(ds1.Objects[objectIdx].X)) sw.PushUint32(uint32(ds1.Objects[objectIdx].X))
// sw.PushUint32(uint32(ds1.Objects[objectIdx].Y)) sw.PushUint32(uint32(ds1.Objects[objectIdx].Y))
//
// for _, path := range ds1.Objects[objectIdx].Paths { for _, path := range ds1.Objects[objectIdx].Paths {
// sw.PushUint32(uint32(path.Position.X())) sw.PushUint32(uint32(path.Position.X()))
// sw.PushUint32(uint32(path.Position.Y())) sw.PushUint32(uint32(path.Position.Y()))
//
// if ds1.version >= v15 { if ds1.version >= v15 {
// sw.PushUint32(uint32(path.Action)) sw.PushUint32(uint32(path.Action))
// } }
// } }
// } }
// } }
//

View File

@ -3,9 +3,6 @@ package d2ds1
import ( import (
"testing" "testing"
"log"
"os"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2path" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2path"
) )
@ -98,8 +95,8 @@ func exampleData() *DS1 {
result := &DS1{ result := &DS1{
ds1Layers: &ds1Layers{ ds1Layers: &ds1Layers{
width: 20, width: 2,
height: 80, height: 2,
Floors: layerGroup{ Floors: layerGroup{
// number of floors (one floor) // number of floors (one floor)
{ {
@ -188,35 +185,13 @@ func exampleData() *DS1 {
return result return result
} }
func TestDS1_Load(t *testing.T) { func TestDS1_MarshalUnmarshal(t *testing.T) {
testFile, fileErr := os.Open("testdata/testdata.ds1") ds1 := exampleData()
if fileErr != nil {
t.Error("cannot open test data file")
return
}
data := make([]byte, 0) data := ds1.Marshal()
buf := make([]byte, 16)
for {
numRead, err := testFile.Read(buf)
data = append(data, buf[:numRead]...)
if err != nil {
break
}
}
_, loadErr := Unmarshal(data) _, loadErr := Unmarshal(data)
if loadErr != nil { if loadErr != nil {
t.Error(loadErr) t.Error(loadErr)
} }
err := testFile.Close()
if err != nil {
t.Fail()
log.Print(err)
}
} }