This is pretty awful, but will let me wire up items more easily without needing to do the big refactor into independent menu handlers
129 lines
2.6 KiB
Go
129 lines
2.6 KiB
Go
package assetstore
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"log"
|
|
|
|
"code.ur.gs/lupine/ordoor/internal/data"
|
|
"code.ur.gs/lupine/ordoor/internal/maps"
|
|
)
|
|
|
|
type Map struct {
|
|
assets *AssetStore
|
|
set *Set
|
|
Rect image.Rectangle
|
|
|
|
raw *maps.GameMap
|
|
}
|
|
|
|
// Map loads a game map with the given name (e.g. "Chapter01")
|
|
func (a *AssetStore) Map(name string) (*Map, error) {
|
|
name = canonical(name)
|
|
|
|
if m, ok := a.maps[name]; ok {
|
|
return m, nil
|
|
}
|
|
log.Printf("Loading map %v", name)
|
|
|
|
mapFile, err := a.lookup(name, "map", "Maps", "MultiMaps")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
txtFile, err := a.lookup(name, "txt", "Maps", "MultiMaps")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
raw, err := maps.LoadGameMapByFiles(mapFile, txtFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// The set for a map is small and frequently referenced, so load it here
|
|
set, err := a.Set(raw.MapSetName())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
m := &Map{
|
|
Rect: raw.Rect(),
|
|
assets: a,
|
|
raw: raw,
|
|
set: set,
|
|
}
|
|
|
|
a.maps[canonical(name)] = m
|
|
|
|
return m, nil
|
|
}
|
|
|
|
func (m *Map) LoadSprites() error {
|
|
// Eager load the sprites we use
|
|
for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ {
|
|
for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ {
|
|
for z := 0; z < maps.MaxHeight; z++ {
|
|
if _, err := m.SpritesForCell(x, y, z); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// FIXME: get rid of this
|
|
func (m *Map) Cell(x, y, z int) *maps.Cell {
|
|
return m.raw.At(x, y, z)
|
|
}
|
|
|
|
// SpritesForCell returns the sprites needed to correctly render this cell.
|
|
// They should be rendered from first to last to get the correct ordering
|
|
func (m *Map) SpritesForCell(x, y, z int) ([]*Sprite, error) {
|
|
cell := m.raw.At(x, y, z)
|
|
sprites := make([]*Sprite, 0, 4)
|
|
|
|
for _, ref := range []maps.ObjRef{cell.Surface, cell.Right, cell.Left, cell.Center} {
|
|
if !ref.IsActive() {
|
|
continue
|
|
}
|
|
|
|
obj, err := m.set.Object(ref.Index())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Failed to get object for %#+v: %v", ref, err)
|
|
}
|
|
|
|
sprite, err := obj.Sprite(ref.Sprite())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sprites = append(sprites, sprite)
|
|
}
|
|
if chr := m.CharacterAt(x, y, z); chr != nil {
|
|
// Look up the correct animation, get the frame, boom
|
|
anim, err := m.assets.CharacterAnimation(chr.Type, data.AnimActionNone)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sprites = append(sprites, anim.Frames[0])
|
|
}
|
|
|
|
return sprites, nil
|
|
}
|
|
|
|
func (m *Map) CharacterAt(x, y, z int) *maps.Character {
|
|
// FIXME: don't iterate
|
|
for i, _ := range m.raw.Characters {
|
|
chr := &m.raw.Characters[i]
|
|
if chr.XPos == x && chr.YPos == y && z == 1 { // FIXME: sort out ZPos
|
|
return chr
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|