106 lines
2.0 KiB
Go
106 lines
2.0 KiB
Go
package assetstore
|
|
|
|
import (
|
|
"image"
|
|
"log"
|
|
|
|
"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: image.Rect(
|
|
int(raw.MinWidth),
|
|
int(raw.MinLength),
|
|
int(raw.MaxWidth),
|
|
int(raw.MaxLength),
|
|
),
|
|
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
|
|
}
|
|
|
|
// 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, err
|
|
}
|
|
|
|
sprite, err := obj.Sprite(ref.Sprite())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sprites = append(sprites, sprite)
|
|
}
|
|
|
|
return sprites, nil
|
|
}
|