OpenDiablo2/d2common/d2data/animation_data.go

84 lines
2.0 KiB
Go

package d2data
import (
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
)
const (
numCofNameBytes = 8
numFlagBytes = 144
)
// AnimationDataRecord represents a single entry in the animation data dictionary file
type AnimationDataRecord struct {
// COFName is the name of the COF file used for this animation
COFName string
// FramesPerDirection specifies how many frames are in each direction
FramesPerDirection int
// AnimationSpeed represents a value of X where the rate is a ration of (x/255) at 25FPS
AnimationSpeed int
// Flags are used in keyframe triggers
Flags []byte
}
// AnimationData represents all of the animation data records, mapped by the COF index
type AnimationData map[string][]*AnimationDataRecord
// LoadAnimationData loads the animation data table into the global AnimationData dictionary
func LoadAnimationData(rawData []byte) (AnimationData, error) {
animdata := make(AnimationData)
streamReader := d2datautils.CreateStreamReader(rawData)
for !streamReader.EOF() {
var dataCount int
b, err := streamReader.ReadInt32()
if err != nil {
return nil, err
}
dataCount = int(b)
for i := 0; i < dataCount; i++ {
cofNameBytes, err := streamReader.ReadBytes(numCofNameBytes)
if err != nil {
return nil, err
}
fpd, err := streamReader.ReadInt32()
if err != nil {
return nil, err
}
animSpeed, err := streamReader.ReadInt32()
if err != nil {
return nil, err
}
data := &AnimationDataRecord{
COFName: strings.ReplaceAll(string(cofNameBytes), string(byte(0)), ""),
FramesPerDirection: int(fpd),
AnimationSpeed: int(animSpeed),
}
flagBytes, err := streamReader.ReadBytes(numFlagBytes)
if err != nil {
return nil, err
}
data.Flags = flagBytes
cofIndex := strings.ToLower(data.COFName)
if _, found := animdata[cofIndex]; !found {
animdata[cofIndex] = make([]*AnimationDataRecord, 0)
}
animdata[cofIndex] = append(animdata[cofIndex], data)
}
}
return animdata, nil
}