doodle/pkg/level/publishing/publishing.go

95 lines
2.5 KiB
Go
Raw Permalink Normal View History

/*
Package publishing contains functionality for "publishing" a Level, which
involves the writing and reading of custom doodads embedded inside
the levels.
Free tiers of the game will not read or write embedded doodads into
levels.
*/
package publishing
import (
"fmt"
"sort"
"git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/doodads"
"git.kirsle.net/apps/doodle/pkg/level"
"git.kirsle.net/apps/doodle/pkg/log"
)
/*
Level "Publishing" functions, involving the writing and reading of embedded
doodads within level files.
*/
// Publish writes a published level file, with embedded doodads included.
func Publish(lvl *level.Level, filename string, includeBuiltins bool) (*level.Level, error) {
// Get and embed the doodads.
builtins, customs := GetUsedDoodadNames(lvl)
if includeBuiltins {
log.Debug("including builtins: %+v", builtins)
customs = append(customs, builtins...)
}
for _, filename := range customs {
log.Debug("Embed filename: %s", filename)
doodad, err := doodads.LoadFromEmbeddable(filename, lvl)
if err != nil {
return nil, fmt.Errorf("couldn't load doodad %s: %s", filename, err)
}
bin, err := doodad.Serialize()
if err != nil {
return nil, fmt.Errorf("couldn't serialize doodad %s: %s", filename, err)
}
// Embed it.
lvl.SetFile(balance.EmbeddedDoodadsBasePath+filename, bin)
}
log.Info("Publish: write file to %s", filename)
err := lvl.WriteFile(filename)
return lvl, err
}
// GetUsedDoodadNames returns the lists of doodad filenames in use in a level,
// bucketed by built-in or custom user doodads.
func GetUsedDoodadNames(lvl *level.Level) (builtin []string, custom []string) {
// Collect all the doodad names in use in this level.
unique := map[string]interface{}{}
names := []string{}
if lvl != nil {
for _, actor := range lvl.Actors {
if _, ok := unique[actor.Filename]; ok {
continue
}
unique[actor.Filename] = nil
names = append(names, actor.Filename)
}
}
// Identify which of the doodads are built-ins.
// builtin = []string{}
builtinMap := map[string]interface{}{}
// custom := []string{}
if builtins, err := doodads.ListBuiltin(); err == nil {
for _, filename := range builtins {
if _, ok := unique[filename]; ok {
builtin = append(builtin, filename)
builtinMap[filename] = nil
}
}
}
for _, name := range names {
if _, ok := builtinMap[name]; ok {
continue
}
custom = append(custom, name)
}
sort.Strings(builtin)
sort.Strings(custom)
return builtin, custom
}