mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-17 18:06:03 -05: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
5706a1c19a
commit
a33117fb56
@ -2,6 +2,7 @@ package d2ds1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
@ -56,10 +57,9 @@ 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
|
||||
unknown2 uint32
|
||||
npcIndexes []int
|
||||
dirty bool // when modifying tiles, need to perform upkeep on ds1 state
|
||||
unknown1 []byte
|
||||
unknown2 uint32
|
||||
}
|
||||
|
||||
// Files returns a list of file path strings.
|
||||
@ -323,35 +323,42 @@ func (ds1 *DS1) NumberOfWallLayers() int {
|
||||
}
|
||||
|
||||
// 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{})
|
||||
}
|
||||
}
|
||||
func (ds1 *DS1) SetNumberOfWallLayers(n int32) error {
|
||||
if n > d2enum.MaxNumberOfWalls {
|
||||
return fmt.Errorf("cannot set number of walls to %d: number of walls is greater than %d", n, d2enum.MaxNumberOfWalls)
|
||||
}
|
||||
|
||||
// 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]
|
||||
// ugh, I don't know, WHY do I nned to use
|
||||
// helper variable, but other way
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
// 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.dirty = true
|
||||
ds1.update()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
func (ds1 *DS1) SetNumberOfFloorLayers(n int32) {
|
||||
// calculate, how much walls is missing
|
||||
missingFloors := n - ds1.numberOfFloorLayers
|
||||
func (ds1 *DS1) SetNumberOfFloorLayers(n int32) error {
|
||||
if n > d2enum.MaxNumberOfFloors {
|
||||
return fmt.Errorf("cannot set number of floors to %d: number is greater than %d", n, d2enum.MaxNumberOfFloors)
|
||||
}
|
||||
|
||||
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{})
|
||||
newFloors := ds1.tiles[y][x].Floors
|
||||
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 == ds1.numberOfFloorLayers {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
ds1.dirty = true
|
||||
@ -396,6 +407,8 @@ func (ds1 *DS1) SetNumberOfFloorLayers(n int32) {
|
||||
}
|
||||
|
||||
ds1.numberOfFloorLayers = n
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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))
|
||||
|
||||
maxWalls := ds1.numberOfWallLayers
|
||||
|
||||
for y := range ds1.tiles {
|
||||
for x := range ds1.tiles[y] {
|
||||
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
|
||||
}
|
||||
@ -733,7 +765,8 @@ func (ds1 *DS1) loadSubstitutions(br *d2datautils.StreamReader) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (ds1 *DS1) setupStreamLayerTypes() []d2enum.LayerStreamType {
|
||||
// GetStreamLayerTypes returns layers used in ds1
|
||||
func (ds1 *DS1) GetStreamLayerTypes() []d2enum.LayerStreamType {
|
||||
var layerStream []d2enum.LayerStreamType
|
||||
|
||||
if ds1.version < v4 {
|
||||
@ -804,7 +837,6 @@ func (ds1 *DS1) loadNPCs(br *d2datautils.StreamReader) error {
|
||||
for idx, ds1Obj := range ds1.objects {
|
||||
if ds1Obj.X == int(npcX) && ds1Obj.Y == int(npcY) {
|
||||
objIdx = idx
|
||||
ds1.npcIndexes = append(ds1.npcIndexes, idx)
|
||||
|
||||
break
|
||||
}
|
||||
@ -869,7 +901,7 @@ func (ds1 *DS1) loadLayerStreams(br *d2datautils.StreamReader) error {
|
||||
0x0F, 0x10, 0x11, 0x12, 0x14,
|
||||
}
|
||||
|
||||
layerStreamTypes := ds1.setupStreamLayerTypes()
|
||||
layerStreamTypes := ds1.GetStreamLayerTypes()
|
||||
|
||||
for _, layerStreamType := range layerStreamTypes {
|
||||
for y := 0; y < int(ds1.height); y++ {
|
||||
@ -990,7 +1022,7 @@ func (ds1 *DS1) Marshal() []byte {
|
||||
}
|
||||
|
||||
func (ds1 *DS1) encodeLayers(sw *d2datautils.StreamWriter) {
|
||||
layerStreamTypes := ds1.setupStreamLayerTypes()
|
||||
layerStreamTypes := ds1.GetStreamLayerTypes()
|
||||
|
||||
for _, layerStreamType := range layerStreamTypes {
|
||||
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) {
|
||||
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
|
||||
sw.PushUint32(uint32(len(ds1.npcIndexes)))
|
||||
sw.PushUint32(uint32(len(objectsWithPaths)))
|
||||
|
||||
// Step 5.2 - enoce npcs' paths
|
||||
for _, i := range ds1.npcIndexes {
|
||||
sw.PushUint32(uint32(len(ds1.objects[i].Paths)))
|
||||
sw.PushUint32(uint32(ds1.objects[i].X))
|
||||
sw.PushUint32(uint32(ds1.objects[i].Y))
|
||||
for objectIdx := range objectsWithPaths {
|
||||
sw.PushUint32(uint32(len(ds1.objects[objectIdx].Paths)))
|
||||
sw.PushUint32(uint32(ds1.objects[objectIdx].X))
|
||||
sw.PushUint32(uint32(ds1.objects[objectIdx].Y))
|
||||
|
||||
for _, j := range ds1.objects[i].Paths {
|
||||
sw.PushUint32(uint32(j.Position.X()))
|
||||
sw.PushUint32(uint32(j.Position.Y()))
|
||||
for _, path := range ds1.objects[objectIdx].Paths {
|
||||
sw.PushUint32(uint32(path.Position.X()))
|
||||
sw.PushUint32(uint32(path.Position.Y()))
|
||||
|
||||
if ds1.version >= v15 {
|
||||
sw.PushUint32(uint32(j.Action))
|
||||
sw.PushUint32(uint32(path.Action))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,6 @@ func exampleDS1() *DS1 {
|
||||
numberOfFloorLayers: 1,
|
||||
numberOfShadowLayers: 1,
|
||||
numberOfSubstitutionLayers: 1,
|
||||
npcIndexes: []int{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -490,11 +489,16 @@ func TestDS1_NumberOfWalls(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDS1_SetNumberOfWalls(t *testing.T) {
|
||||
var err error
|
||||
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -538,11 +545,16 @@ func TestDS1_NumberOfFloors(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDS1_SetNumberOfFloors(t *testing.T) {
|
||||
var err error
|
||||
|
||||
ds1 := exampleDS1()
|
||||
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -625,7 +640,7 @@ func TestDS1_SetSubstitutionGroups(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDS1_setupStreamLayerTypes(t *testing.T) {
|
||||
func TestDS1_GetStreamLayerTypes(t *testing.T) {
|
||||
ds1 := exampleDS1()
|
||||
|
||||
lst := []d2enum.LayerStreamType{
|
||||
@ -636,7 +651,7 @@ func TestDS1_setupStreamLayerTypes(t *testing.T) {
|
||||
d2enum.LayerStreamSubstitute,
|
||||
}
|
||||
|
||||
layerStreamTypes := ds1.setupStreamLayerTypes()
|
||||
layerStreamTypes := ds1.GetStreamLayerTypes()
|
||||
|
||||
if len(lst) != len(layerStreamTypes) {
|
||||
t.Fatal("unexpected length")
|
||||
|
Loading…
Reference in New Issue
Block a user