Added basic game save.

This commit is contained in:
Daniel Schmidt 2023-04-22 20:43:09 +02:00
parent da5f6d49ef
commit 5e4ccab2cd
4 changed files with 67 additions and 23 deletions

View File

@ -17,9 +17,9 @@ type Actor struct {
HP int
MaxHP int
Gold int
Artifacts StringSet
Cards StringSet
StatusEffects StringSet
Artifacts *StringSet
Cards *StringSet
StatusEffects *StringSet
}
func (a Actor) IsNone() bool {

View File

@ -15,6 +15,7 @@ import (
"io"
"log"
"math/rand"
"os"
"sort"
"time"
)
@ -241,6 +242,18 @@ func (s *Session) GetGameState() GameState {
func (s *Session) SetGameState(state GameState) {
s.state = state
// Save after each fight
if s.state == GameStateFight {
save, err := s.GobEncode()
if err != nil {
s.log.Println("Error saving file:", save)
} else {
if err := os.WriteFile("./session.save", save, 0666); err != nil {
s.log.Println("Error saving file:", save)
}
}
}
switch s.state {
case GameStateFight:
s.SetupFight()
@ -254,6 +267,7 @@ func (s *Session) SetGameState(state GameState) {
func (s *Session) SetEvent(id string) {
s.currentEvent = ""
if _, ok := s.resources.Events[id]; ok {
s.currentEvent = id
s.eventHistory = append(s.eventHistory, id)
_, _ = s.resources.Events[id].OnEnter.Call(CreateContext("type_id", id))
}

View File

@ -7,53 +7,63 @@ import (
"github.com/samber/lo"
)
type StringSet map[string]struct{}
func NewStringSet() StringSet {
return StringSet{}
// StringSet represents a string set that can be serialized by Gob.
//
// Note: As the GobDecode needs to overwrite its receiver we need to have the map
// behind a struct pointer.
type StringSet struct {
values map[string]struct{}
}
func (s StringSet) Has(val string) bool {
_, ok := s[val]
func NewStringSet() *StringSet {
return &StringSet{
values: map[string]struct{}{},
}
}
func (s *StringSet) Has(val string) bool {
_, ok := s.values[val]
return ok
}
func (s StringSet) Add(val string) {
s[val] = struct{}{}
func (s *StringSet) Add(val string) {
s.values[val] = struct{}{}
}
func (s StringSet) Remove(val string) {
delete(s, val)
func (s *StringSet) Remove(val string) {
delete(s.values, val)
}
func (s StringSet) Append(vals ...string) {
func (s *StringSet) Append(vals ...string) {
for _, val := range vals {
s.Add(val)
}
}
func (s StringSet) Clear() {
for key := range s {
delete(s, key)
func (s *StringSet) Clear() {
for key := range s.values {
delete(s.values, key)
}
}
func (s StringSet) ToSlice() []string {
return lo.Keys(s)
func (s *StringSet) ToSlice() []string {
return lo.Keys(s.values)
}
func (s StringSet) Clone() StringSet {
return util.CopyMap(s)
func (s *StringSet) Clone() *StringSet {
return &StringSet{values: util.CopyMap(s.values)}
}
func (s StringSet) GobEncode() ([]byte, error) {
func (s *StringSet) GobEncode() ([]byte, error) {
buf := &bytes.Buffer{}
enc := gob.NewEncoder(buf)
err := enc.Encode(s.ToSlice())
return buf.Bytes(), err
}
func (s StringSet) GobDecode(data []byte) error {
func (s *StringSet) GobDecode(data []byte) error {
*s = StringSet{values: map[string]struct{}{}}
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)

View File

@ -53,6 +53,26 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch m.choices.selected {
case ChoiceContinue:
if saved, err := os.ReadFile("./session.save"); err == nil {
f, err := os.OpenFile("./logs/S "+strings.ReplaceAll(time.Now().Format(time.DateTime), ":", "-")+".txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
panic(err)
}
session := game.NewSession(
game.WithLogging(log.New(f, "SESSION ", log.Ldate|log.Ltime|log.Lshortfile)),
lo.Ternary(os.Getenv("PG_DEBUG") == "1", game.WithDebugEnabled("127.0.0.1:8272"), nil),
)
err = session.GobDecode(saved)
if err != nil {
log.Println("Error loading save:", err)
} else {
m.choices = m.choices.Clear()
return gameview.New(m, m.zones, session), cmd
}
}
case ChoiceNewGame:
_ = os.Mkdir("./logs", 0777)
f, err := os.OpenFile("./logs/S "+strings.ReplaceAll(time.Now().Format(time.DateTime), ":", "-")+".txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)