Skip to content

Commit a0f45ec

Browse files
authored
Merge pull request #16 from The-Mod-Elephant/feature/AreaJsonTests
feat(area): Add area json tests
2 parents af2df01 + e2f42fa commit a0f45ec

9 files changed

Lines changed: 18932 additions & 101 deletions

File tree

bg/all.go

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package bg
33
import (
44
"encoding/binary"
55
"encoding/json"
6+
"fmt"
67
"io"
7-
"strings"
8+
"unicode/utf8"
89
)
910

1011
type BG interface {
@@ -26,35 +27,56 @@ func max(x, y int) int {
2627
return y
2728
}
2829

29-
type LongString [32]byte
30-
31-
func (l *LongString) String() string {
32-
return string(l[:])
30+
func parseArray(r io.ReadSeeker, start uint32, data any) error {
31+
if _, err := r.Seek(int64(start), io.SeekStart); err != nil {
32+
return err
33+
}
34+
return binary.Read(r, binary.LittleEndian, data)
3335
}
3436

35-
func (l *LongString) MarshalJSON() ([]byte, error) {
36-
return []byte(l.String()), nil
37+
func asciiBytesToString(b []byte) string {
38+
out := ""
39+
for _, c := range b {
40+
out += string(c)
41+
}
42+
return out
3743
}
3844

45+
type LongString [32]byte
46+
3947
func (l *LongString) UnmarshalJSON(b []byte) error {
40-
for i := range min(len(b)-2, 32) {
41-
l[i] = b[i+1]
48+
var decoded string
49+
if err := json.Unmarshal(b, &decoded); err != nil {
50+
return fmt.Errorf("%v, error for byte slice of %v", err, b)
51+
}
52+
for i := 0; len(decoded) > 0 && i < 32; i++ {
53+
asciiRune, size := utf8.DecodeRune([]byte(decoded))
54+
l[i] = byte(asciiRune)
55+
decoded = decoded[size:]
4256
}
4357
return nil
4458
}
4559

46-
type Signature [4]byte
60+
func (l *LongString) MarshalJSON() ([]byte, error) {
61+
return json.Marshal(l.String())
62+
}
4763

48-
func (s Signature) String() string {
49-
return string(s[:])
64+
func (l *LongString) Valid() bool {
65+
return len(l) != 0
5066
}
5167

68+
func (l *LongString) String() string {
69+
return asciiBytesToString(l[:])
70+
}
71+
72+
type Signature [4]byte
73+
5274
func (s *Signature) UnmarshalJSON(b []byte) error {
53-
if len(b) > 2 {
54-
for i := range min(len(b)-2, 4) {
55-
s[i] = b[i+1]
56-
}
75+
var decoded string
76+
if err := json.Unmarshal(b, &decoded); err != nil {
77+
return err
5778
}
79+
*s = Signature([]byte(decoded))
5880
return nil
5981
}
6082

@@ -66,18 +88,18 @@ func (s *Signature) Valid() bool {
6688
return len(s) != 0
6789
}
6890

69-
type Version [4]byte
70-
71-
func (v Version) String() string {
72-
return string(v[0:])
91+
func (s Signature) String() string {
92+
return asciiBytesToString(s[:])
7393
}
7494

95+
type Version [4]byte
96+
7597
func (v *Version) UnmarshalJSON(b []byte) error {
76-
if len(b) > 2 {
77-
for i := range min(len(b)-2, 4) {
78-
v[i] = b[i+1]
79-
}
98+
var decoded string
99+
if err := json.Unmarshal(b, &decoded); err != nil {
100+
return err
80101
}
102+
*v = Version([]byte(decoded))
81103
return nil
82104
}
83105

@@ -89,17 +111,21 @@ func (v *Version) Valid() bool {
89111
return len(v) != 0
90112
}
91113

92-
type Resref [8]byte
93-
94-
func NewResref(name string) Resref {
95-
return Resref([]byte(name))
114+
func (v Version) String() string {
115+
return asciiBytesToString(v[:])
96116
}
97117

118+
type Resref [8]byte
119+
98120
func (r *Resref) UnmarshalJSON(b []byte) error {
99-
if len(b) > 2 {
100-
for i := range min(len(b)-2, 8) {
101-
r[i] = b[i+1]
102-
}
121+
var decoded string
122+
if err := json.Unmarshal(b, &decoded); err != nil {
123+
return fmt.Errorf("%v, error for byte slice of %v", err, b)
124+
}
125+
for i := 0; len(decoded) > 0 && i < 8; i++ {
126+
asciiRune, size := utf8.DecodeRune([]byte(decoded))
127+
r[i] = byte(asciiRune)
128+
decoded = decoded[size:]
103129
}
104130
return nil
105131
}
@@ -113,14 +139,7 @@ func (r *Resref) Valid() bool {
113139
}
114140

115141
func (r Resref) String() string {
116-
return strings.Split(string(r[0:]), "\x00")[0]
142+
return asciiBytesToString(r[:])
117143
}
118144

119145
type strref uint32
120-
121-
func parseArray(r io.ReadSeeker, start uint32, out any) error {
122-
if _, err := r.Seek(int64(start), io.SeekStart); err != nil {
123-
return err
124-
}
125-
return binary.Read(r, binary.LittleEndian, out)
126-
}

bg/are.go

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"io"
77
"maps"
8+
"reflect"
89
"slices"
910
)
1011

@@ -45,9 +46,9 @@ type AreaHeader struct {
4546
AmbientCount uint16 `json:"ambient_count"`
4647
AmbientOffset uint32 `json:"ambient_offset"`
4748
VariableOffset uint32 `json:"variable_offset"`
48-
VariableCount uint16 `json:"variable_count"`
49+
VariableCount uint32 `json:"variable_count"`
50+
TiledObjectFlagOffset uint16 `json:"tiled_object_flag_offset"`
4951
TiledObjectFlagCount uint16 `json:"tiled_object_flag_count"`
50-
TiledObjectFlagOffset uint32 `json:"tiled_object_flag_offset"`
5152
Script Resref `json:"script"`
5253
ExploredSize uint32 `json:"explored_size"`
5354
ExploredOffset uint32 `json:"explored_offset"`
@@ -343,7 +344,7 @@ type AreaSong struct {
343344

344345
type AreaRestEncounter struct {
345346
Name LongString `json:"name"`
346-
RandomCreatureString [10]uint32 `json:"random_creature_string"`
347+
RandomCreatureString [10]strref `json:"random_creature_string"`
347348
RandomCreature [10]Resref `json:"random_creature"`
348349
RandomCreatureNum uint16 `json:"random_creature_num"`
349350
Difficulty uint16 `json:"difficulty"`
@@ -354,7 +355,7 @@ type AreaRestEncounter struct {
354355
Activated uint16 `json:"activated"`
355356
ProbabilityDay uint16 `json:"probability_day"`
356357
ProbabilityNight uint16 `json:"probability_night"`
357-
Unused [14]uint32 `json:"unused"`
358+
Unused [56]uint8 `json:"unused"`
358359
}
359360

360361
type Area struct {
@@ -379,6 +380,64 @@ type Area struct {
379380
Filename string `json:"-"`
380381
}
381382

383+
func (a *Area) Equal(other *Area) bool {
384+
if !reflect.DeepEqual(a.AreaHeader, other.AreaHeader) {
385+
return false
386+
}
387+
if !slices.Equal(a.Actors, other.Actors) {
388+
return false
389+
}
390+
if !slices.Equal(a.Regions, other.Regions) {
391+
return false
392+
}
393+
if !slices.Equal(a.SpawnPoints, other.SpawnPoints) {
394+
return false
395+
}
396+
if !slices.Equal(a.Entrances, other.Entrances) {
397+
return false
398+
}
399+
if !slices.Equal(a.Containers, other.Containers) {
400+
return false
401+
}
402+
if !slices.Equal(a.Items, other.Items) {
403+
return false
404+
}
405+
if !slices.Equal(a.Vertices, other.Vertices) {
406+
return false
407+
}
408+
if !slices.Equal(a.Ambients, other.Ambients) {
409+
return false
410+
}
411+
if !slices.Equal(a.Variables, other.Variables) {
412+
return false
413+
}
414+
if !slices.Equal(a.ExploredBitmasks, other.ExploredBitmasks) {
415+
return false
416+
}
417+
if !slices.Equal(a.Doors, other.Doors) {
418+
return false
419+
}
420+
if !slices.Equal(a.Animations, other.Animations) {
421+
return false
422+
}
423+
if !slices.Equal(a.MapNotes, other.MapNotes) {
424+
return false
425+
}
426+
if !slices.Equal(a.TiledObjects, other.TiledObjects) {
427+
return false
428+
}
429+
if !slices.Equal(a.Traps, other.Traps) {
430+
return false
431+
}
432+
if !reflect.DeepEqual(a.Songs, other.Songs) {
433+
return false
434+
}
435+
if !reflect.DeepEqual(a.RestInterruptions, other.RestInterruptions) {
436+
return false
437+
}
438+
return true
439+
}
440+
382441
func OpenArea(r io.ReadSeeker) (*Area, error) {
383442
area := Area{}
384443

@@ -505,24 +564,24 @@ func (are *Area) Write(w io.Writer) error {
505564
return err
506565
}
507566
order := map[uint32]func() error{
508-
are.ActorsOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Actors) },
509-
are.RegionOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Regions) },
510-
are.SpawnPointOffset: func() error { return binary.Write(w, binary.LittleEndian, are.SpawnPoints) },
511-
are.EntranceOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Entrances) },
512-
are.ContainerOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Containers) },
513-
are.ItemOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Items) },
514-
are.VertexOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Vertices) },
515-
are.AmbientOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Ambients) },
516-
are.VariableOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Variables) },
517-
are.TiledObjectFlagOffset: func() error { return binary.Write(w, binary.LittleEndian, are.TiledObjects) },
518-
are.ExploredOffset: func() error { return binary.Write(w, binary.LittleEndian, are.ExploredBitmasks) },
519-
are.DoorsOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Doors) },
520-
are.AnimationOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Animations) },
521-
are.TiledObjectOffset: func() error { return binary.Write(w, binary.LittleEndian, are.TiledObjects) },
522-
are.SongEntriesOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Songs) },
523-
are.RestInterruptionsOffset: func() error { return binary.Write(w, binary.LittleEndian, are.RestInterruptions) },
524-
are.AutomapOffset: func() error { return binary.Write(w, binary.LittleEndian, are.MapNotes) },
525-
are.ProjectileTrapsOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Traps) },
567+
are.ActorsOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Actors) },
568+
are.RegionOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Regions) },
569+
are.SpawnPointOffset: func() error { return binary.Write(w, binary.LittleEndian, are.SpawnPoints) },
570+
are.EntranceOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Entrances) },
571+
are.ContainerOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Containers) },
572+
are.ItemOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Items) },
573+
are.VertexOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Vertices) },
574+
are.AmbientOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Ambients) },
575+
are.VariableOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Variables) },
576+
uint32(are.TiledObjectFlagOffset): func() error { return binary.Write(w, binary.LittleEndian, are.TiledObjects) },
577+
are.ExploredOffset: func() error { return binary.Write(w, binary.LittleEndian, are.ExploredBitmasks) },
578+
are.DoorsOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Doors) },
579+
are.AnimationOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Animations) },
580+
are.TiledObjectOffset: func() error { return binary.Write(w, binary.LittleEndian, are.TiledObjects) },
581+
are.SongEntriesOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Songs) },
582+
are.RestInterruptionsOffset: func() error { return binary.Write(w, binary.LittleEndian, are.RestInterruptions) },
583+
are.AutomapOffset: func() error { return binary.Write(w, binary.LittleEndian, are.MapNotes) },
584+
are.ProjectileTrapsOffset: func() error { return binary.Write(w, binary.LittleEndian, are.Traps) },
526585
}
527586
for _, key := range slices.Sorted(maps.Keys(order)) {
528587
if err := order[key](); err != nil {

0 commit comments

Comments
 (0)