Files
ordoor/internal/assetstore/ani.go

140 lines
3.4 KiB
Go
Raw Normal View History

2020-04-16 15:30:47 +01:00
package assetstore
import (
2020-06-13 15:07:32 +01:00
"fmt"
"code.ur.gs/lupine/ordoor/internal/data"
2020-04-16 15:30:47 +01:00
"code.ur.gs/lupine/ordoor/internal/idx"
)
type Animation struct {
Frames []*Sprite
}
func (a *AssetStore) AnimationsIndex() (*idx.Idx, error) {
if a.idx != nil {
return a.idx, nil
}
filename, err := a.lookup("WarHammer", "idx", "Idx")
if err != nil {
return nil, err
}
idx, err := idx.Load(filename)
if err != nil {
return nil, err
}
a.idx = idx
return idx, nil
}
func (a *AssetStore) AnimationsObject() (*Object, error) {
if a.aniObj != nil {
return a.aniObj, nil
}
filename, err := a.lookup("WarHammer", "ani", "Anim")
if err != nil {
return nil, err
}
obj, err := a.ObjectByPath(filename)
if err != nil {
return nil, err
}
a.aniObj = obj
return obj, nil
}
2020-06-13 23:10:21 +01:00
func (a *AssetStore) Animation(groupIdx int, recId int, compass int) (*Animation, error) {
realIdx, err := a.AnimationsIndex()
2020-04-16 15:30:47 +01:00
if err != nil {
return nil, err
}
2020-06-13 23:10:21 +01:00
// FIXME: are we using the right value if we need to make this change?
if compass == 0 {
compass = 8
}
2020-04-16 15:30:47 +01:00
obj, err := a.AnimationsObject()
if err != nil {
return nil, err
}
2020-06-13 23:10:21 +01:00
group := realIdx.Groups[groupIdx]
2020-04-16 15:30:47 +01:00
if group.Spec.Count == 0 {
return &Animation{}, nil
}
2020-06-13 23:10:21 +01:00
var det *idx.Detail
for i, rec := range group.Records {
if /*int(rec.ActionID) == int(action) && */ int(rec.Compass) == compass {
det = &group.Details[i]
}
}
if det == nil {
return nil, fmt.Errorf("Couldn't find anim (%v %v %v)", groupIdx, recId, compass)
}
2020-04-16 15:30:47 +01:00
first := int(group.Spec.SpriteIdx) + int(det.FirstSprite)
last := int(group.Spec.SpriteIdx) + int(det.LastSprite)
count := last - first + 1
sprites, err := obj.Sprites(first, count)
if err != nil {
return nil, err
}
return &Animation{Frames: sprites}, nil
}
2020-06-13 15:07:32 +01:00
2020-06-13 23:10:21 +01:00
func (a *AssetStore) CharacterAnimation(ctype data.CharacterType, action data.AnimAction, compass int) (*Animation, error) {
2020-06-13 15:07:32 +01:00
ha, err := a.HasAction()
if err != nil {
return nil, err
}
if !ha.Check(ctype, action) {
return nil, fmt.Errorf("character %s: animation %s: not available", ctype, action)
}
// FIXME: we still need to be able to go from CTYPE to GROUP. In particular,
// squad leaders seem to be a modification on top of a previous group, which
// is a bit awkward. For now, hardcode it. How are captain modifiers stored?
group, ok := map[data.CharacterType]int{
data.CharacterTypeTactical: 1, // Has captain
data.CharacterTypeAssault: 3, // Has captain
data.CharacterTypeDevastator: 5,
data.CharacterTypeTerminator: 6, // Has captain
data.CharacterTypeApothecary: 8,
data.CharacterTypeTechmarine: 9,
data.CharacterTypeChaplain: 10,
data.CharacterTypeLibrarian: 11,
data.CharacterTypeCaptain: 12,
data.CharacterTypeChaosMarine: 13,
data.CharacterTypeChaosLord: 14,
data.CharacterTypeChaosChaplain: 15,
data.CharacterTypeChaosSorcerer: 16,
data.CharacterTypeChaosTerminator: 17,
data.CharacterTypeKhorneBerserker: 18,
data.CharacterTypeBloodThirster: 19, // This is a rotating thing?
data.CharacterTypeBloodLetter: 20,
data.CharacterTypeFleshHound: 21,
data.CharacterTypeLordOfChange: 22, // Another rotating thing?
data.CharacterTypeFlamer: 23,
data.CharacterTypePinkHorror: 24,
data.CharacterTypeBlueHorror: 25,
data.CharacterTypeChaosCultist: 26,
}[ctype]
if !ok {
return nil, fmt.Errorf("Unknown character type: %s", ctype)
}
2020-06-13 23:10:21 +01:00
return a.Animation(group, int(action), compass)
2020-06-13 15:07:32 +01:00
}