2020-01-26 00:39:13 -05:00
|
|
|
package d2cof
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
2020-09-12 16:25:09 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
|
2020-01-31 23:18:11 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
2020-01-26 00:39:13 -05:00
|
|
|
)
|
|
|
|
|
2020-06-28 22:32:34 -04:00
|
|
|
// COF is a structure that represents a COF file.
|
2020-01-26 00:39:13 -05:00
|
|
|
type COF struct {
|
|
|
|
NumberOfDirections int
|
|
|
|
FramesPerDirection int
|
|
|
|
NumberOfLayers int
|
|
|
|
Speed int
|
|
|
|
CofLayers []CofLayer
|
|
|
|
CompositeLayers map[d2enum.CompositeType]int
|
|
|
|
AnimationFrames []d2enum.AnimationFrame
|
|
|
|
Priority [][][]d2enum.CompositeType
|
|
|
|
}
|
|
|
|
|
2020-06-28 22:32:34 -04:00
|
|
|
// Load loads a COF file.
|
|
|
|
func Load(fileData []byte) (*COF, error) {
|
2020-01-26 00:39:13 -05:00
|
|
|
result := &COF{}
|
2020-09-08 15:58:35 -04:00
|
|
|
streamReader := d2datautils.CreateStreamReader(fileData)
|
2020-01-26 00:39:13 -05:00
|
|
|
result.NumberOfLayers = int(streamReader.GetByte())
|
|
|
|
result.FramesPerDirection = int(streamReader.GetByte())
|
|
|
|
result.NumberOfDirections = int(streamReader.GetByte())
|
2020-06-28 22:32:34 -04:00
|
|
|
|
|
|
|
streamReader.SkipBytes(21) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
result.Speed = int(streamReader.GetByte())
|
2020-06-28 22:32:34 -04:00
|
|
|
|
|
|
|
streamReader.SkipBytes(3) //nolint:gomnd // Unknown data
|
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
result.CofLayers = make([]CofLayer, result.NumberOfLayers)
|
2020-06-22 11:53:44 -04:00
|
|
|
result.CompositeLayers = make(map[d2enum.CompositeType]int)
|
2020-06-28 22:32:34 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
for i := 0; i < result.NumberOfLayers; i++ {
|
|
|
|
layer := CofLayer{}
|
|
|
|
layer.Type = d2enum.CompositeType(streamReader.GetByte())
|
|
|
|
layer.Shadow = streamReader.GetByte()
|
|
|
|
layer.Selectable = streamReader.GetByte() != 0
|
|
|
|
layer.Transparent = streamReader.GetByte() != 0
|
|
|
|
layer.DrawEffect = d2enum.DrawEffect(streamReader.GetByte())
|
2020-06-28 22:32:34 -04:00
|
|
|
weaponClassStr := streamReader.ReadBytes(4) //nolint:gomnd // Binary data
|
2020-09-06 17:09:05 -04:00
|
|
|
layer.WeaponClass = d2enum.WeaponClassFromString(strings.TrimSpace(strings.ReplaceAll(string(weaponClassStr), string(byte(0)), "")))
|
2020-01-26 00:39:13 -05:00
|
|
|
result.CofLayers[i] = layer
|
|
|
|
result.CompositeLayers[layer.Type] = i
|
|
|
|
}
|
2020-06-28 22:32:34 -04:00
|
|
|
|
2020-06-20 21:07:36 -04:00
|
|
|
animationFrameBytes := streamReader.ReadBytes(result.FramesPerDirection)
|
2020-01-26 00:39:13 -05:00
|
|
|
result.AnimationFrames = make([]d2enum.AnimationFrame, result.FramesPerDirection)
|
2020-06-28 22:32:34 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
for i := range animationFrameBytes {
|
|
|
|
result.AnimationFrames[i] = d2enum.AnimationFrame(animationFrameBytes[i])
|
|
|
|
}
|
2020-06-28 22:32:34 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
priorityLen := result.FramesPerDirection * result.NumberOfDirections * result.NumberOfLayers
|
|
|
|
result.Priority = make([][][]d2enum.CompositeType, result.NumberOfDirections)
|
2020-06-20 21:07:36 -04:00
|
|
|
priorityBytes := streamReader.ReadBytes(priorityLen)
|
2020-01-26 00:39:13 -05:00
|
|
|
priorityIndex := 0
|
2020-06-28 22:32:34 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
for direction := 0; direction < result.NumberOfDirections; direction++ {
|
|
|
|
result.Priority[direction] = make([][]d2enum.CompositeType, result.FramesPerDirection)
|
|
|
|
for frame := 0; frame < result.FramesPerDirection; frame++ {
|
|
|
|
result.Priority[direction][frame] = make([]d2enum.CompositeType, result.NumberOfLayers)
|
|
|
|
for i := 0; i < result.NumberOfLayers; i++ {
|
|
|
|
result.Priority[direction][frame][i] = d2enum.CompositeType(priorityBytes[priorityIndex])
|
|
|
|
priorityIndex++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-06-28 22:32:34 -04:00
|
|
|
|
2020-01-26 00:39:13 -05:00
|
|
|
return result, nil
|
|
|
|
}
|