2020-05-31 11:18:26 +01:00
|
|
|
package game
|
2020-05-30 23:42:01 +01:00
|
|
|
|
2020-06-02 17:44:39 +01:00
|
|
|
import (
|
2020-06-02 17:51:54 +01:00
|
|
|
"encoding/json"
|
2020-06-02 17:44:39 +01:00
|
|
|
"fmt"
|
2020-06-02 17:51:54 +01:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path"
|
2020-06-02 17:44:39 +01:00
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
)
|
2020-05-31 00:06:14 +01:00
|
|
|
|
2020-05-30 23:42:01 +01:00
|
|
|
// World describes a self contained universe and everything in it
|
|
|
|
type World struct {
|
2020-06-02 17:51:54 +01:00
|
|
|
Instances map[uuid.UUID]Instance `json:"instances"`
|
|
|
|
|
|
|
|
// dataPath is the location for the data to be stored
|
|
|
|
dataPath string
|
2020-05-30 23:42:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Instance describes a single entity or instance of an entity in the world
|
|
|
|
type Instance struct {
|
2020-06-02 17:44:39 +01:00
|
|
|
// id is a unique ID for this instance
|
2020-05-31 00:06:14 +01:00
|
|
|
id uuid.UUID
|
2020-06-02 17:44:39 +01:00
|
|
|
|
|
|
|
// pos represents where this instance is in the world
|
|
|
|
pos Position
|
2020-05-30 23:42:01 +01:00
|
|
|
}
|
|
|
|
|
2020-06-02 17:51:54 +01:00
|
|
|
const kWorldFileName = "rove-world.json"
|
|
|
|
|
2020-05-30 23:42:01 +01:00
|
|
|
// NewWorld creates a new world object
|
2020-06-02 17:51:54 +01:00
|
|
|
func NewWorld(data string) *World {
|
2020-06-02 17:44:39 +01:00
|
|
|
return &World{
|
2020-06-02 17:51:54 +01:00
|
|
|
Instances: make(map[uuid.UUID]Instance),
|
|
|
|
dataPath: data,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// path returns the full path to the data file
|
|
|
|
func (w *World) path() string {
|
|
|
|
return path.Join(w.dataPath, kWorldFileName)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load will load the accountant from data
|
|
|
|
func (w *World) Load() error {
|
|
|
|
// Don't load anything if the file doesn't exist
|
|
|
|
_, err := os.Stat(w.path())
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
fmt.Printf("File %s didn't exist, loading with fresh world data\n", w.path())
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if b, err := ioutil.ReadFile(w.path()); err != nil {
|
|
|
|
return err
|
|
|
|
} else if err := json.Unmarshal(b, &w); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save will save the accountant data out
|
|
|
|
func (w *World) Save() error {
|
|
|
|
if b, err := json.MarshalIndent(w, "", "\t"); err != nil {
|
|
|
|
return err
|
|
|
|
} else {
|
|
|
|
if err := ioutil.WriteFile(w.path(), b, os.ModePerm); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-06-02 17:44:39 +01:00
|
|
|
}
|
2020-06-02 17:51:54 +01:00
|
|
|
return nil
|
2020-05-30 23:42:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Adds an instance to the game
|
2020-05-31 00:06:14 +01:00
|
|
|
func (w *World) CreateInstance() uuid.UUID {
|
|
|
|
id := uuid.New()
|
2020-05-30 23:42:01 +01:00
|
|
|
|
|
|
|
// Initialise the instance
|
|
|
|
instance := Instance{
|
|
|
|
id: id,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Append the instance to the list
|
2020-06-02 17:51:54 +01:00
|
|
|
w.Instances[id] = instance
|
2020-05-30 23:42:01 +01:00
|
|
|
|
|
|
|
return id
|
|
|
|
}
|
2020-06-02 17:44:39 +01:00
|
|
|
|
|
|
|
// GetPosition returns the position of a given instance
|
|
|
|
func (w World) GetPosition(id uuid.UUID) (Position, error) {
|
2020-06-02 17:51:54 +01:00
|
|
|
if i, ok := w.Instances[id]; ok {
|
2020-06-02 17:44:39 +01:00
|
|
|
return i.pos, nil
|
|
|
|
} else {
|
|
|
|
return Position{}, fmt.Errorf("no instance matching id")
|
|
|
|
}
|
|
|
|
}
|