M10: byten, hemresan och levelcheck
All checks were successful
release / build-release (push) Successful in 1m37s
All checks were successful
release / build-release (push) Successful in 1m37s
Resor med byten: en bana kan ha next som pekar på en delbana (kind leg, syns inte på bankartan). När man klivit av rätt tåg fortsätter samma omgång på nästa station med klocka, plånbok, sällskap och räknare; par-tiden adderas, dimma och folk är nya, en Byte!-banner visas och HUD:en visar resmålet via bytesstationen. Tidsgräns och missade tåg gäller hela resan. level.ValidateChains kräver sammanhängande kedjor. Nya resor: 007 Akihabara -> Ueno -> Asakusa och finalen 008 Tokyo (två våningar) -> Nippori -> Narita flygplats. Slutscen när sista huvudbanan klaras första gången: planet lyfter, resan summeras, eftertexter; Progress.StoryCleared sparas; flaggan -ending. tools/levelcheck ritar banorna och rapporterar problem. HUD-nivån kortas när mätarna tar plats; poängraden radbryts. Skärmdumpar och docs uppdaterade. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -71,6 +71,7 @@ type Options struct {
|
||||
Mute bool // inget ljud
|
||||
SavePath string // sparfil ("" = standardplatsen)
|
||||
NoSave bool // läs sparfilen men skriv aldrig
|
||||
Ending bool // öppna slutscenen direkt (tester/skärmdumpar)
|
||||
Mode string // navigeringsläge från start: "list" eller "signs" (tomt = sparfilens)
|
||||
}
|
||||
|
||||
@@ -137,18 +138,40 @@ func New(opt Options) (*Game, error) {
|
||||
g.Wallet.Card = opt.CardYen
|
||||
}
|
||||
|
||||
if opt.LevelID != "" {
|
||||
switch {
|
||||
case opt.Ending:
|
||||
g.scene = NewEndingScene(g)
|
||||
case opt.LevelID != "":
|
||||
s, err := g.startLevel(opt.LevelID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
g.scene = s
|
||||
} else {
|
||||
default:
|
||||
g.scene = NewMapScene(g)
|
||||
}
|
||||
return g, nil
|
||||
}
|
||||
|
||||
// chainAfter är resans fortsättning efter banan id (delbanorna via next).
|
||||
func (g *Game) chainAfter(id string) []*level.Level {
|
||||
if c := level.ChainOf(g.Levels, id); len(c) > 1 {
|
||||
return c[1:]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// isLastMain rapporterar om banan är storyns sista huvudbana.
|
||||
func (g *Game) isLastMain(id string) bool {
|
||||
var last *level.Level
|
||||
for _, l := range g.Levels {
|
||||
if !l.IsSide() && !l.IsLeg() && (last == nil || l.Order > last.Order) {
|
||||
last = l
|
||||
}
|
||||
}
|
||||
return last != nil && last.ID == id
|
||||
}
|
||||
|
||||
func loadCatalog() (*progress.Catalog, error) {
|
||||
sk, err := res.ReadFile("data", "skills.json")
|
||||
if err != nil {
|
||||
@@ -240,7 +263,7 @@ func (g *Game) runOptions(id string, seed rng.Seed) sim.RunOptions {
|
||||
return sim.RunOptions{
|
||||
Dict: g.Assets.Dict, Know: g.Know, Wallet: g.Wallet, Debuffs: g.Profile.Debuffs, Seed: seed,
|
||||
Extra: eff.Stats, FogRadius: eff.FogRadius, Landmarks: eff.Landmarks, FreeGates: eff.FreeGates,
|
||||
RevealAll: eff.Reveal[id], InfiniteBattery: eff.Battery, Mode: g.Mode,
|
||||
RevealAll: eff.Reveal[id], InfiniteBattery: eff.Battery, Mode: g.Mode, Chain: g.chainAfter(id),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,12 +304,13 @@ func (g *Game) startLevel(id string) (*LevelScene, error) {
|
||||
|
||||
// LevelOutcome är vad en avslutad bana gav i progression (för resultatskärmen).
|
||||
type LevelOutcome struct {
|
||||
XP int
|
||||
LevelUps int
|
||||
FirstClear bool
|
||||
NewItems []string
|
||||
NewPoints int
|
||||
Unlocked []string // banor som öppnades
|
||||
XP int
|
||||
LevelUps int
|
||||
FirstClear bool
|
||||
NewItems []string
|
||||
NewPoints int
|
||||
Unlocked []string // banor som öppnades
|
||||
StoryCleared bool // sista huvudbanan klarades för första gången: visa slutet
|
||||
}
|
||||
|
||||
// levelEnded appliceras exakt en gång när en bana avgjorts: debuffar,
|
||||
@@ -323,6 +347,10 @@ func (g *Game) levelEnded(run *sim.Run, id string) LevelOutcome {
|
||||
out.Unlocked = append(out.Unlocked, l.ID)
|
||||
}
|
||||
}
|
||||
if g.isLastMain(id) && !g.Progress.StoryCleared {
|
||||
g.Progress.StoryCleared = true
|
||||
out.StoryCleared = true
|
||||
}
|
||||
}
|
||||
g.State.Current = nil
|
||||
g.Save()
|
||||
|
||||
Reference in New Issue
Block a user