M9b: folk, filer, reklam, sorl och vagnval
All checks were successful
release / build-release (push) Successful in 1m33s

Folk på stationen (NPC:er som vandrar, kliver av tåg och går mot
utgången, blockerar spelaren men inte varandra), vänster-/högerfiler
som bromsar på fel sida, bredare gångar, reklamaffischer (clutter),
japanskt sorl i loop (noise), vagnval med kvinnovagn (stort avdrag med
man i sällskapet, tidsstyrd), kömarkeringar på perrongen, trängsel per
vagn (bonus för tom vagn, svettig-debuff och svårare resa i full vagn,
släpp förbi passagerare) och att folk kliver av innan man får gå på.
Ny bana 005 Ueno. Skärmdumpsverktyget kan filtrera på bana/skript.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 12:33:44 +02:00
parent 8fca14e42d
commit de61568e44
49 changed files with 1568 additions and 136 deletions

View File

@@ -12,18 +12,31 @@ type Ride struct {
Timer float64 // sekunder kvar vid aktuell station
StopSec float64
GotOff int // index där spelaren klev av, -1 = inte än
// Trängsel: vid stationer där man inte ska av vill andra passagerare ut.
Crowd int // vagnens trängselnivå 0–2
WantsOut []bool // per station: någon vill förbi
LetPass bool // spelaren har släppt förbi vid aktuell station
Blocked int // stationer där ingen släpptes förbi (avdrag)
}
// Tid per station efter trängsel: 2,5 / 2,0 / 1,5 s.
const rideStopSec = 2.5
// RideStopSec är tiden per station för en trängselnivå.
func RideStopSec(crowd int) float64 { return rideStopSec - 0.5*float64(max(0, min(2, crowd))) }
// NewRide bygger linjen: fillers är andra stationsnamn (blandas), dest läggs
// på en seedad plats (aldrig först) om det är rätt tåg, annars utelämnas det.
func NewRide(seed rng.Seed, dest string, fillers []string, stops int, correctTrain bool) *Ride {
// crowd (0–2) ger kortare tid per station och passagerare som vill förbi.
func NewRide(seed rng.Seed, dest string, fillers []string, stops int, correctTrain bool, crowd int) *Ride {
r := newRand(seed, "ride")
f := append([]string(nil), fillers...)
r.shuffle(len(f), func(i, j int) { f[i], f[j] = f[j], f[i] })
stops = max(2, stops)
g := &Ride{StopSec: rideStopSec, Timer: rideStopSec, GotOff: -1, Dest: -1}
crowd = max(0, min(2, crowd))
sec := RideStopSec(crowd)
g := &Ride{StopSec: sec, Timer: sec, GotOff: -1, Dest: -1, Crowd: crowd}
if correctTrain {
g.Dest = 1 + r.intn(stops-1)
}
@@ -38,9 +51,19 @@ func NewRide(seed rng.Seed, dest string, fillers []string, stops int, correctTra
g.Stops = append(g.Stops, UnknownStop) // slut på namn: en namnlös station
}
}
g.WantsOut = make([]bool, len(g.Stops))
chance := [...]float64{0, 0.4, 0.7}[crowd]
for i := range g.Stops {
if i != g.Dest && r.float() < chance {
g.WantsOut[i] = true
}
}
return g
}
// NeedsLetPass rapporterar om någon vill förbi vid aktuell station just nu.
func (g *Ride) NeedsLetPass() bool { return g.WantsOut[g.Index] && !g.LetPass }
// UnknownStop används när det inte finns fler stationsnamn att ta av.
const UnknownStop = "・・・"
@@ -58,10 +81,17 @@ func (g *Ride) Update(in Input, dt float64) {
g.success = g.Index == g.Dest
return
}
if in.MoveX < 0 && g.NeedsLetPass() {
g.LetPass = true // kliv åt sidan
}
g.Timer -= dt
if g.Timer <= 0 {
if g.NeedsLetPass() {
g.Blocked++
}
g.Index++
g.Timer = g.StopSec
g.LetPass = false
if g.Index >= len(g.Stops) {
g.Index = len(g.Stops) - 1
g.done = true // åkte till slutstationen utan att kliva av