mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-09-29 22:56:07 -04:00
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>
This commit is contained in:
parent
5e62b12bc4
commit
4e7ec3e843
@ -2,6 +2,7 @@ package d2ds1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
@ -59,7 +60,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
|
||||||
unknown2 uint32
|
unknown2 uint32
|
||||||
npcIndexes []int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Files returns a list of file path strings.
|
// Files returns a list of file path strings.
|
||||||
@ -323,35 +323,42 @@ func (ds1 *DS1) NumberOfWallLayers() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetNumberOfWallLayers sets new number of tiles' walls
|
// SetNumberOfWallLayers sets new number of tiles' walls
|
||||||
func (ds1 *DS1) SetNumberOfWallLayers(n int32) {
|
func (ds1 *DS1) SetNumberOfWallLayers(n int32) error {
|
||||||
for y := range ds1.tiles {
|
if n > d2enum.MaxNumberOfWalls {
|
||||||
for x := range ds1.tiles[y] {
|
return fmt.Errorf("cannot set number of walls to %d: number of walls is greater than %d", n, d2enum.MaxNumberOfWalls)
|
||||||
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 y := range ds1.tiles {
|
||||||
for x := range ds1.tiles[y] {
|
for x := range ds1.tiles[y] {
|
||||||
newWalls := make([]Wall, n)
|
// ugh, I don't know, WHY do I nned to use
|
||||||
for v := int32(0); v < n; v++ {
|
// helper variable, but other way
|
||||||
newWalls[v] = ds1.tiles[y][x].Walls[v]
|
// simply doesn't work
|
||||||
|
newWalls := ds1.tiles[y][x].Walls
|
||||||
|
for v := int32(0); v < (n - int32(len(ds1.tiles[y][x].Walls))); v++ {
|
||||||
|
newWalls = append(newWalls, Wall{0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.tiles[y][x].Walls = newWalls
|
ds1.tiles[y][x].Walls = newWalls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if n = number of walls, do nothing
|
||||||
|
if n == ds1.numberOfWallLayers {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for y := range ds1.tiles {
|
||||||
|
for x := range ds1.tiles[y] {
|
||||||
|
ds1.tiles[y][x].Walls = ds1.tiles[y][x].Walls[:n]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ds1.numberOfWallLayers = n
|
ds1.numberOfWallLayers = n
|
||||||
|
|
||||||
|
ds1.dirty = true
|
||||||
|
ds1.update()
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumberOfFloorLayers returns the number of floor layers per tile
|
// NumberOfFloorLayers returns the number of floor layers per tile
|
||||||
@ -364,21 +371,25 @@ func (ds1 *DS1) NumberOfFloorLayers() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetNumberOfFloorLayers sets new number of tiles' floors
|
// SetNumberOfFloorLayers sets new number of tiles' floors
|
||||||
func (ds1 *DS1) SetNumberOfFloorLayers(n int32) {
|
func (ds1 *DS1) SetNumberOfFloorLayers(n int32) error {
|
||||||
// calculate, how much walls is missing
|
if n > d2enum.MaxNumberOfFloors {
|
||||||
missingFloors := n - ds1.numberOfFloorLayers
|
return fmt.Errorf("cannot set number of floors to %d: number is greater than %d", n, d2enum.MaxNumberOfFloors)
|
||||||
|
}
|
||||||
|
|
||||||
for y := range ds1.tiles {
|
for y := range ds1.tiles {
|
||||||
for x := range ds1.tiles[y] {
|
for x := range ds1.tiles[y] {
|
||||||
for v := int32(0); v < missingFloors; v++ {
|
newFloors := ds1.tiles[y][x].Floors
|
||||||
ds1.tiles[y][x].Floors = append(ds1.tiles[y][x].Floors, Floor{})
|
for v := int32(0); v < (n - int32(len(ds1.tiles[y][x].Floors))); v++ {
|
||||||
|
newFloors = append(newFloors, Floor{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ds1.tiles[y][x].Floors = newFloors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if n = number of walls, do nothing
|
// if n = number of walls, do nothing
|
||||||
if n == ds1.numberOfFloorLayers {
|
if n == ds1.numberOfFloorLayers {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.dirty = true
|
ds1.dirty = true
|
||||||
@ -396,6 +407,8 @@ func (ds1 *DS1) SetNumberOfFloorLayers(n int32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ds1.numberOfFloorLayers = n
|
ds1.numberOfFloorLayers = n
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumberOfShadowLayers returns the number of shadow layers per tile
|
// NumberOfShadowLayers returns the number of shadow layers per tile
|
||||||
@ -434,6 +447,7 @@ func (ds1 *DS1) update() {
|
|||||||
ds1.SetSize(len(ds1.tiles[0]), len(ds1.tiles))
|
ds1.SetSize(len(ds1.tiles[0]), len(ds1.tiles))
|
||||||
|
|
||||||
maxWalls := ds1.numberOfWallLayers
|
maxWalls := ds1.numberOfWallLayers
|
||||||
|
|
||||||
for y := range ds1.tiles {
|
for y := range ds1.tiles {
|
||||||
for x := range ds1.tiles[y] {
|
for x := range ds1.tiles[y] {
|
||||||
if len(ds1.tiles[y][x].Walls) > int(maxWalls) {
|
if len(ds1.tiles[y][x].Walls) > int(maxWalls) {
|
||||||
@ -442,7 +456,25 @@ func (ds1 *DS1) update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ds1.SetNumberOfWallLayers(maxWalls)
|
err := ds1.SetNumberOfWallLayers(maxWalls)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
maxFloors := ds1.numberOfFloorLayers
|
||||||
|
|
||||||
|
for y := range ds1.tiles {
|
||||||
|
for x := range ds1.tiles[y] {
|
||||||
|
if len(ds1.tiles[y][x].Floors) > int(maxFloors) {
|
||||||
|
maxFloors = int32(len(ds1.tiles[y][x].Floors))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ds1.SetNumberOfFloorLayers(maxFloors)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
}
|
||||||
|
|
||||||
ds1.dirty = false
|
ds1.dirty = false
|
||||||
}
|
}
|
||||||
@ -733,7 +765,8 @@ func (ds1 *DS1) loadSubstitutions(br *d2datautils.StreamReader) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds1 *DS1) setupStreamLayerTypes() []d2enum.LayerStreamType {
|
// GetStreamLayerTypes returns layers used in ds1
|
||||||
|
func (ds1 *DS1) GetStreamLayerTypes() []d2enum.LayerStreamType {
|
||||||
var layerStream []d2enum.LayerStreamType
|
var layerStream []d2enum.LayerStreamType
|
||||||
|
|
||||||
if ds1.version < v4 {
|
if ds1.version < v4 {
|
||||||
@ -804,7 +837,6 @@ func (ds1 *DS1) loadNPCs(br *d2datautils.StreamReader) error {
|
|||||||
for idx, ds1Obj := range ds1.objects {
|
for idx, ds1Obj := range ds1.objects {
|
||||||
if ds1Obj.X == int(npcX) && ds1Obj.Y == int(npcY) {
|
if ds1Obj.X == int(npcX) && ds1Obj.Y == int(npcY) {
|
||||||
objIdx = idx
|
objIdx = idx
|
||||||
ds1.npcIndexes = append(ds1.npcIndexes, idx)
|
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -869,7 +901,7 @@ func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error {
|
|||||||
0x0F, 0x10, 0x11, 0x12, 0x14,
|
0x0F, 0x10, 0x11, 0x12, 0x14,
|
||||||
}
|
}
|
||||||
|
|
||||||
layerStreamTypes := ds1.setupStreamLayerTypes()
|
layerStreamTypes := ds1.GetStreamLayerTypes()
|
||||||
|
|
||||||
for _, layerStreamType := range layerStreamTypes {
|
for _, layerStreamType := range layerStreamTypes {
|
||||||
for y := 0; y < int(ds1.height); y++ {
|
for y := 0; y < int(ds1.height); y++ {
|
||||||
@ -990,7 +1022,7 @@ func (ds1 *DS1) Marshal() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) {
|
func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) {
|
||||||
layerStreamTypes := ds1.setupStreamLayerTypes()
|
layerStreamTypes := ds1.GetStreamLayerTypes()
|
||||||
|
|
||||||
for _, layerStreamType := range layerStreamTypes {
|
for _, layerStreamType := range layerStreamTypes {
|
||||||
for y := 0; y < int(ds1.height); y++ {
|
for y := 0; y < int(ds1.height); y++ {
|
||||||
@ -1022,21 +1054,29 @@ func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ds1 *DS1) encodeNPCs(sw *d2datautils.StreamWriter) {
|
func (ds1 *DS1) encodeNPCs(sw *d2datautils.StreamWriter) {
|
||||||
|
objectsWithPaths := make([]int, 0)
|
||||||
|
|
||||||
|
for n, obj := range ds1.objects {
|
||||||
|
if len(obj.Paths) != 0 {
|
||||||
|
objectsWithPaths = append(objectsWithPaths, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Step 5.1 - encode npc's
|
// Step 5.1 - encode npc's
|
||||||
sw.PushUint32(uint32(len(ds1.npcIndexes)))
|
sw.PushUint32(uint32(len(objectsWithPaths)))
|
||||||
|
|
||||||
// Step 5.2 - enoce npcs' paths
|
// Step 5.2 - enoce npcs' paths
|
||||||
for _, i := range ds1.npcIndexes {
|
for objectIdx := range objectsWithPaths {
|
||||||
sw.PushUint32(uint32(len(ds1.objects[i].Paths)))
|
sw.PushUint32(uint32(len(ds1.objects[objectIdx].Paths)))
|
||||||
sw.PushUint32(uint32(ds1.objects[i].X))
|
sw.PushUint32(uint32(ds1.objects[objectIdx].X))
|
||||||
sw.PushUint32(uint32(ds1.objects[i].Y))
|
sw.PushUint32(uint32(ds1.objects[objectIdx].Y))
|
||||||
|
|
||||||
for _, j := range ds1.objects[i].Paths {
|
for _, path := range ds1.objects[objectIdx].Paths {
|
||||||
sw.PushUint32(uint32(j.Position.X()))
|
sw.PushUint32(uint32(path.Position.X()))
|
||||||
sw.PushUint32(uint32(j.Position.Y()))
|
sw.PushUint32(uint32(path.Position.Y()))
|
||||||
|
|
||||||
if ds1.version >= v15 {
|
if ds1.version >= v15 {
|
||||||
sw.PushUint32(uint32(j.Action))
|
sw.PushUint32(uint32(path.Action))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ func exampleDS1() *DS1 {
|
|||||||
numberOfFloorLayers: 1,
|
numberOfFloorLayers: 1,
|
||||||
numberOfShadowLayers: 1,
|
numberOfShadowLayers: 1,
|
||||||
numberOfSubstitutionLayers: 1,
|
numberOfSubstitutionLayers: 1,
|
||||||
npcIndexes: []int{},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,11 +489,16 @@ func TestDS1_NumberOfWalls(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDS1_SetNumberOfWalls(t *testing.T) {
|
func TestDS1_SetNumberOfWalls(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
|
||||||
ds1 := exampleDS1()
|
ds1 := exampleDS1()
|
||||||
|
|
||||||
newNumber := int32(2)
|
newNumber := int32(4)
|
||||||
|
|
||||||
ds1.SetNumberOfWallLayers(newNumber)
|
err = ds1.SetNumberOfWallLayers(newNumber)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error setting number of walls: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
test := func(ds1 *DS1) {
|
test := func(ds1 *DS1) {
|
||||||
if len(ds1.tiles[0][0].Walls) != int(newNumber) {
|
if len(ds1.tiles[0][0].Walls) != int(newNumber) {
|
||||||
@ -506,13 +510,16 @@ func TestDS1_SetNumberOfWalls(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := testIfRestorable(ds1, test); err != nil {
|
if err = testIfRestorable(ds1, test); err != nil {
|
||||||
t.Errorf("unable to restore: %v", err)
|
t.Errorf("unable to restore: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newNumber = 1
|
newNumber = 1
|
||||||
|
|
||||||
ds1.SetNumberOfWallLayers(newNumber)
|
err = ds1.SetNumberOfWallLayers(newNumber)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error setting number of walls: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
test = func(ds1 *DS1) {
|
test = func(ds1 *DS1) {
|
||||||
if len(ds1.tiles[0][0].Walls) != int(newNumber) {
|
if len(ds1.tiles[0][0].Walls) != int(newNumber) {
|
||||||
@ -524,7 +531,7 @@ func TestDS1_SetNumberOfWalls(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := testIfRestorable(ds1, test); err != nil {
|
if err = testIfRestorable(ds1, test); err != nil {
|
||||||
t.Errorf("unable to restore: %v", err)
|
t.Errorf("unable to restore: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,11 +545,16 @@ func TestDS1_NumberOfFloors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDS1_SetNumberOfFloors(t *testing.T) {
|
func TestDS1_SetNumberOfFloors(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
|
||||||
ds1 := exampleDS1()
|
ds1 := exampleDS1()
|
||||||
|
|
||||||
newNumber := int32(2)
|
newNumber := int32(2)
|
||||||
|
|
||||||
ds1.SetNumberOfFloorLayers(newNumber)
|
err = ds1.SetNumberOfFloorLayers(newNumber)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error setting number of floors: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
test := func(ds1 *DS1) {
|
test := func(ds1 *DS1) {
|
||||||
if len(ds1.tiles[0][0].Floors) != int(newNumber) {
|
if len(ds1.tiles[0][0].Floors) != int(newNumber) {
|
||||||
@ -554,13 +566,16 @@ func TestDS1_SetNumberOfFloors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := testIfRestorable(ds1, test); err != nil {
|
if err = testIfRestorable(ds1, test); err != nil {
|
||||||
t.Errorf("unable to restore: %v", err)
|
t.Errorf("unable to restore: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newNumber = 1
|
newNumber = 1
|
||||||
|
|
||||||
ds1.SetNumberOfFloorLayers(newNumber)
|
err = ds1.SetNumberOfFloorLayers(newNumber)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error setting number of floors: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
test = func(ds1 *DS1) {
|
test = func(ds1 *DS1) {
|
||||||
if len(ds1.tiles[0][0].Floors) != int(newNumber) {
|
if len(ds1.tiles[0][0].Floors) != int(newNumber) {
|
||||||
@ -572,7 +587,7 @@ func TestDS1_SetNumberOfFloors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := testIfRestorable(ds1, test); err != nil {
|
if err = testIfRestorable(ds1, test); err != nil {
|
||||||
t.Errorf("unable to restore: %v", err)
|
t.Errorf("unable to restore: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -625,7 +640,7 @@ func TestDS1_SetSubstitutionGroups(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDS1_setupStreamLayerTypes(t *testing.T) {
|
func TestDS1_GetStreamLayerTypes(t *testing.T) {
|
||||||
ds1 := exampleDS1()
|
ds1 := exampleDS1()
|
||||||
|
|
||||||
lst := []d2enum.LayerStreamType{
|
lst := []d2enum.LayerStreamType{
|
||||||
@ -636,7 +651,7 @@ func TestDS1_setupStreamLayerTypes(t *testing.T) {
|
|||||||
d2enum.LayerStreamSubstitute,
|
d2enum.LayerStreamSubstitute,
|
||||||
}
|
}
|
||||||
|
|
||||||
layerStreamTypes := ds1.setupStreamLayerTypes()
|
layerStreamTypes := ds1.GetStreamLayerTypes()
|
||||||
|
|
||||||
if len(lst) != len(layerStreamTypes) {
|
if len(lst) != len(layerStreamTypes) {
|
||||||
t.Fatal("unexpected length")
|
t.Fatal("unexpected length")
|
||||||
|
Loading…
Reference in New Issue
Block a user