M8: progression, items, bankarta och sparfil
All checks were successful
release / build-release (push) Successful in 1m46s
All checks were successful
release / build-release (push) Successful in 1m46s
- internal/progress: katalog (skills.json 12 noder, items.json 25 items) med validering; XP/nivåer (150·n(n+1)/2) och skillpoäng; skillträd med krav och kostnad; items per plats med buffar, genvägar (JR Pass, kartor, powerbank) och färgton; banresultat och upplåsning (huvudbanor i ordning, sidospår efter föräldern); 33 %-regeln som test - internal/save: versionerad JSON med kunskap, plånbok, debuffar, progression och pågående bana + seed; atomisk skrivning; migrering; ~/.config/metro-puzzle-jp/save.json resp. %AppData% - sim: RunOptions får Extra/FogRadius/Landmarks/FreeGates/RevealAll/ InfiniteBattery; luck påverkar trängselzonen; Fog.RevealAll och extra landmärken - game: bankarta i spelbrädesstil ersätter menyn (⟳ återupptar med sparad seed), skillträd (T), garderob (I), butik i kiosken (B), XP/nivå/items/ upplåsningar på resultatet, spelaren tonas av skins; autospar vid banstart, efter banan och vid köp; flaggor -save/-nosave - level: kind/order/parent/rewards/shop; ny sidobana 002b Kabukicho som belönar skinnet Kimono; 001 belönar Salaryman-skinnet; butikssortiment på 002/003 - tools/shots: demo-sparfil (build/, aldrig den riktiga), bilder av karta, skills, garderob och butik; alla körningar med -nosave - docs/README/wiki uppdaterade Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -17,8 +17,28 @@ import (
|
||||
"strings"
|
||||
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/level"
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/save"
|
||||
)
|
||||
|
||||
// demoSave skriver en sparfil med lite progression så att kartan, skills
|
||||
// och garderoben har något att visa. Används bara av skärmdumparna.
|
||||
func demoSave(path string) error {
|
||||
st := save.New()
|
||||
st.Know.Learn("改札")
|
||||
st.Know.Learn("出口")
|
||||
st.Know.Points = 2
|
||||
st.Progress.RecordLevel("001-flygplatsen", true, 3, 941)
|
||||
st.Progress.RecordLevel("002-shinjuku", true, 2, 760)
|
||||
st.Progress.AddXP(600)
|
||||
st.Progress.Items["skin_salaryman"] = true
|
||||
st.Progress.Items["geta"] = true
|
||||
st.Progress.Items["water_bottle"] = true
|
||||
st.Progress.Equipped["body"] = "skin_salaryman"
|
||||
st.Progress.Equipped["feet"] = "geta"
|
||||
st.Progress.Skills["focus1"] = true
|
||||
return save.Store(path, st)
|
||||
}
|
||||
|
||||
type shot struct {
|
||||
level string
|
||||
script string // $OUT ersätts med doc/img-mappen
|
||||
@@ -29,6 +49,8 @@ type shot struct {
|
||||
// bilderna överlever ändringar i banorna.
|
||||
var shots []shot
|
||||
|
||||
var demo string
|
||||
|
||||
func buildShots(levelsDir string) error {
|
||||
l, err := level.LoadFile(filepath.Join(levelsDir, "001-flygplatsen.json"))
|
||||
if err != nil {
|
||||
@@ -48,6 +70,10 @@ func buildShots(levelsDir string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
toKiosk, err := moves(l, l.SpawnPoint(), l.Find(level.Kiosk)[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l2, err := level.LoadFile(filepath.Join(levelsDir, "002-shinjuku.json"))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -68,8 +94,9 @@ func buildShots(levelsDir string) error {
|
||||
// delvisa översättningen syns; hjälpen lär sedan in nästa ord.
|
||||
known := []string{"-know", "改札,番線,方面", "-seed", "7"}
|
||||
shots = []shot{
|
||||
{"", "wait 10; shot $OUT/menu.png; press l; wait 5; press down; press down; press down; wait 5; shot $OUT/words.png; quit",
|
||||
[]string{"-know", "改札,出口,トイレ", "-points", "3"}},
|
||||
{"", "wait 10; shot $OUT/map.png; press l; wait 5; press down; press down; press down; wait 5; shot $OUT/words.png; press l; wait 3; press t; wait 5; press down; wait 3; shot $OUT/skills.png; press t; wait 3; press i; wait 5; shot $OUT/items.png; quit",
|
||||
[]string{"-know", "改札,出口,トイレ", "-points", "3", "-save", "$DEMO"}},
|
||||
{"001-flygplatsen", toKiosk + "; press b; wait 5; press down; wait 3; shot $OUT/shop.png; quit", []string{"-seed", "7", "-save", "$DEMO"}},
|
||||
{"001-flygplatsen", "move right 4; move down 2; wait 5; shot $OUT/level-001.png; quit", nil},
|
||||
{"002-shinjuku", "move down 6; move right 4; wait 5; shot $OUT/level-002.png; quit", nil},
|
||||
{"001-flygplatsen", toSign + "; wait 5; shot $OUT/sign.png; press h; wait 200; shot $OUT/sign-help.png; wait 200; shot $OUT/sign-learned.png; " + toGoal +
|
||||
@@ -124,6 +151,9 @@ func main() {
|
||||
root := repoRoot()
|
||||
out := filepath.Join(root, "doc", "img")
|
||||
must(os.MkdirAll(out, 0o755))
|
||||
demo = filepath.Join(root, "build", "demo-save.json")
|
||||
must(os.MkdirAll(filepath.Dir(demo), 0o755))
|
||||
must(demoSave(demo))
|
||||
must(buildShots(filepath.Join(root, "resources", "data", "levels")))
|
||||
|
||||
build := exec.Command("go", "run", "./tools/build", "-mode", "debug")
|
||||
@@ -134,12 +164,15 @@ func main() {
|
||||
if runtime.GOOS == "windows" {
|
||||
exe += ".exe"
|
||||
}
|
||||
_ = demo
|
||||
for _, s := range shots {
|
||||
args := []string{"-mute", "-script", strings.ReplaceAll(s.script, "$OUT", out)}
|
||||
args := []string{"-mute", "-nosave", "-script", strings.ReplaceAll(s.script, "$OUT", out)}
|
||||
if s.level != "" {
|
||||
args = append(args, "-level", s.level)
|
||||
}
|
||||
args = append(args, s.args...)
|
||||
for _, a := range s.args {
|
||||
args = append(args, strings.ReplaceAll(a, "$DEMO", demo))
|
||||
}
|
||||
run := exec.Command(exe, args...)
|
||||
run.Dir, run.Stdout, run.Stderr = filepath.Dir(exe), os.Stdout, os.Stderr
|
||||
if err := run.Run(); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user