Finish save.go split: header/player halves, drop inline err
This commit is contained in:
141
game/save.go
141
game/save.go
@@ -177,8 +177,48 @@ func (g *RogueGame) packIdx(obj *Object) int {
|
||||
|
||||
// snapshot captures the complete game state.
|
||||
func (g *RogueGame) snapshot() *SaveState {
|
||||
p := &g.Player
|
||||
st := &SaveState{
|
||||
st := g.snapshotHeader()
|
||||
|
||||
// the map, sans monster pointers (rebuilt on load)
|
||||
st.Places = make([]savedPlace, len(g.Level.Places))
|
||||
for i := range g.Level.Places {
|
||||
st.Places[i] = savedPlace{
|
||||
Ch: g.Level.Places[i].Ch,
|
||||
Flags: g.Level.Places[i].Flags,
|
||||
}
|
||||
}
|
||||
|
||||
// level objects by value; remember their pointers for dest encoding
|
||||
objAt := make(map[*Object]int, len(g.Level.Objects))
|
||||
for i, o := range g.Level.Objects {
|
||||
st.Objects = append(st.Objects, *o)
|
||||
objAt[o] = i
|
||||
}
|
||||
|
||||
st.Player = g.snapshotPlayer()
|
||||
|
||||
// monsters, with chase targets as (kind, index) references
|
||||
for _, m := range g.Level.Monsters {
|
||||
sc := savedCreature{
|
||||
Pos: m.Pos, Turn: m.Turn, Type: m.Type, Disguise: m.Disguise,
|
||||
OldCh: m.OldCh, Flags: m.Flags, Stats: m.Stats,
|
||||
RoomIdx: g.roomIdx(m.Room),
|
||||
}
|
||||
for _, o := range m.Pack {
|
||||
sc.Pack = append(sc.Pack, *o)
|
||||
}
|
||||
|
||||
st.Monsters = append(st.Monsters, sc)
|
||||
st.Dests = append(st.Dests, g.destRefFor(m, objAt))
|
||||
}
|
||||
|
||||
return st
|
||||
}
|
||||
|
||||
// snapshotHeader captures the scalar game state (the field list of
|
||||
// state.c rs_save_file).
|
||||
func (g *RogueGame) snapshotHeader() *SaveState {
|
||||
return &SaveState{
|
||||
Version: saveFormatVersion,
|
||||
Seed: g.Rng.Seed,
|
||||
Dnum: g.Dnum,
|
||||
@@ -226,25 +266,14 @@ func (g *RogueGame) snapshot() *SaveState {
|
||||
AllScore: g.AllScore,
|
||||
Screen: g.scr.Std.Contents(),
|
||||
}
|
||||
}
|
||||
|
||||
// the map, sans monster pointers (rebuilt on load)
|
||||
st.Places = make([]savedPlace, len(g.Level.Places))
|
||||
for i := range g.Level.Places {
|
||||
st.Places[i] = savedPlace{
|
||||
Ch: g.Level.Places[i].Ch,
|
||||
Flags: g.Level.Places[i].Flags,
|
||||
}
|
||||
}
|
||||
// snapshotPlayer captures the player, equipment as pack indices (the
|
||||
// player half of snapshot).
|
||||
func (g *RogueGame) snapshotPlayer() savedPlayer {
|
||||
p := &g.Player
|
||||
|
||||
// level objects by value; remember their pointers for dest encoding
|
||||
objAt := make(map[*Object]int, len(g.Level.Objects))
|
||||
for i, o := range g.Level.Objects {
|
||||
st.Objects = append(st.Objects, *o)
|
||||
objAt[o] = i
|
||||
}
|
||||
|
||||
// the player
|
||||
st.Player = savedPlayer{
|
||||
sp := savedPlayer{
|
||||
Body: savedCreature{
|
||||
Pos: p.Pos, Turn: p.Turn, Type: p.Type, Disguise: p.Disguise,
|
||||
OldCh: p.OldCh, Flags: p.Flags, Stats: p.Stats,
|
||||
@@ -260,25 +289,10 @@ func (g *RogueGame) snapshot() *SaveState {
|
||||
MaxStats: p.MaxStats, VfHit: p.VfHit,
|
||||
}
|
||||
for _, o := range p.Pack {
|
||||
st.Player.Body.Pack = append(st.Player.Body.Pack, *o)
|
||||
sp.Body.Pack = append(sp.Body.Pack, *o)
|
||||
}
|
||||
|
||||
// monsters, with chase targets as (kind, index) references
|
||||
for _, m := range g.Level.Monsters {
|
||||
sc := savedCreature{
|
||||
Pos: m.Pos, Turn: m.Turn, Type: m.Type, Disguise: m.Disguise,
|
||||
OldCh: m.OldCh, Flags: m.Flags, Stats: m.Stats,
|
||||
RoomIdx: g.roomIdx(m.Room),
|
||||
}
|
||||
for _, o := range m.Pack {
|
||||
sc.Pack = append(sc.Pack, *o)
|
||||
}
|
||||
|
||||
st.Monsters = append(st.Monsters, sc)
|
||||
st.Dests = append(st.Dests, g.destRefFor(m, objAt))
|
||||
}
|
||||
|
||||
return st
|
||||
return sp
|
||||
}
|
||||
|
||||
// destRefFor encodes a monster's chase target as a (kind, index)
|
||||
@@ -315,7 +329,32 @@ func (g *RogueGame) destRefFor(m *Monster, objAt map[*Object]int) destRef {
|
||||
|
||||
// applySnapshot rebuilds live game state from a snapshot.
|
||||
func (g *RogueGame) applySnapshot(st *SaveState) {
|
||||
p := &g.Player
|
||||
g.applyHeader(st)
|
||||
|
||||
for i := range g.Level.Places {
|
||||
g.Level.Places[i] = Place{
|
||||
Ch: st.Places[i].Ch,
|
||||
Flags: st.Places[i].Flags,
|
||||
}
|
||||
}
|
||||
|
||||
// level objects
|
||||
g.Level.Objects = nil
|
||||
for i := range st.Objects {
|
||||
o := st.Objects[i]
|
||||
g.Level.Objects = append(g.Level.Objects, &o)
|
||||
}
|
||||
|
||||
g.applyPlayer(st)
|
||||
g.applyMonsters(st)
|
||||
g.applyDests(st)
|
||||
|
||||
g.scr.Std.SetContents(st.Screen)
|
||||
}
|
||||
|
||||
// applyHeader restores the scalar game state (the field list of
|
||||
// applySnapshot).
|
||||
func (g *RogueGame) applyHeader(st *SaveState) {
|
||||
g.Rng.Seed = st.Seed
|
||||
g.Dnum = st.Dnum
|
||||
g.Whoami = st.Whoami
|
||||
@@ -360,22 +399,12 @@ func (g *RogueGame) applySnapshot(st *SaveState) {
|
||||
g.LastScore = st.LastScore
|
||||
g.AllScore = st.AllScore
|
||||
g.Playing = true
|
||||
}
|
||||
|
||||
for i := range g.Level.Places {
|
||||
g.Level.Places[i] = Place{
|
||||
Ch: st.Places[i].Ch,
|
||||
Flags: st.Places[i].Flags,
|
||||
}
|
||||
}
|
||||
|
||||
// level objects
|
||||
g.Level.Objects = nil
|
||||
for i := range st.Objects {
|
||||
o := st.Objects[i]
|
||||
g.Level.Objects = append(g.Level.Objects, &o)
|
||||
}
|
||||
|
||||
// the player
|
||||
// applyPlayer restores the player, resolving equipment pack indices
|
||||
// (the player half of applySnapshot).
|
||||
func (g *RogueGame) applyPlayer(st *SaveState) {
|
||||
p := &g.Player
|
||||
sp := &st.Player
|
||||
p.Pos = sp.Body.Pos
|
||||
p.Turn = sp.Body.Turn
|
||||
@@ -412,11 +441,6 @@ func (g *RogueGame) applySnapshot(st *SaveState) {
|
||||
p.NoFood = sp.NoFood
|
||||
p.MaxStats = sp.MaxStats
|
||||
p.VfHit = sp.VfHit
|
||||
|
||||
g.applyMonsters(st)
|
||||
g.applyDests(st)
|
||||
|
||||
g.scr.Std.SetContents(st.Screen)
|
||||
}
|
||||
|
||||
// applyMonsters rebuilds the monster list and its map index from a
|
||||
@@ -507,7 +531,8 @@ prompt:
|
||||
|
||||
g.FileName = buf
|
||||
|
||||
if err := g.saveFile(g.FileName); err != nil {
|
||||
err := g.saveFile(g.FileName)
|
||||
if err != nil {
|
||||
g.msg("%s", err.Error())
|
||||
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user