M9b: folk, filer, reklam, sorl och vagnval
All checks were successful
release / build-release (push) Successful in 1m33s
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:
@@ -25,16 +25,58 @@ func fillSeats(r *Run, tk *minigame.Ticket) {
|
||||
}
|
||||
}
|
||||
|
||||
// pickCar väljer vagn: låter folk kliva av, väljer sedan den lugnaste vagnen
|
||||
// som inte är kvinnovagn. Hanterar också ett ev. trängselminispel.
|
||||
func pickCar(t *testing.T, r *Run) {
|
||||
t.Helper()
|
||||
g, ok := r.Mini.(*minigame.CarPick)
|
||||
if !ok {
|
||||
t.Fatalf("ingen vagnval pågår (kind=%v)", r.MiniKind)
|
||||
}
|
||||
for g.Alighting > 0 {
|
||||
r.StepMini(frame, minigame.Input{})
|
||||
}
|
||||
best := -1
|
||||
for i, c := range g.Cars {
|
||||
if c.WomenOnly {
|
||||
continue
|
||||
}
|
||||
if best < 0 || c.Crowd < g.Cars[best].Crowd {
|
||||
best = i
|
||||
}
|
||||
}
|
||||
if best < 0 {
|
||||
best = 0
|
||||
}
|
||||
for g.Cursor != best {
|
||||
r.StepMini(frame, minigame.Input{MoveX: 1})
|
||||
}
|
||||
r.StepMini(frame, minigame.Input{Confirm: true})
|
||||
if cr, ok := r.Mini.(*minigame.Crowd); ok {
|
||||
for i := 0; i < 600 && !cr.InZone(); i++ {
|
||||
r.StepMini(frame, minigame.Input{})
|
||||
}
|
||||
r.StepMini(frame, minigame.Input{Confirm: true})
|
||||
}
|
||||
}
|
||||
|
||||
// ride spelar tågresan: kliver av när tåget står vid resmålet. På fel tåg
|
||||
// finns inget resmål, så resan går till slutstationen.
|
||||
// finns inget resmål, så resan går till slutstationen. Släpper förbi folk.
|
||||
func ride(t *testing.T, r *Run) {
|
||||
t.Helper()
|
||||
if r.MiniKind == MiniCarPick {
|
||||
pickCar(t, r)
|
||||
}
|
||||
if r.MiniKind != MiniRide {
|
||||
t.Fatalf("ingen tågresa pågår (kind=%v)", r.MiniKind)
|
||||
}
|
||||
for i := 0; i < 60*120 && r.Mini != nil; i++ {
|
||||
g := r.Mini.(*minigame.Ride)
|
||||
r.StepMini(frame, minigame.Input{Confirm: g.Index == g.Dest})
|
||||
in := minigame.Input{Confirm: g.Index == g.Dest}
|
||||
if g.NeedsLetPass() {
|
||||
in.MoveX = -1
|
||||
}
|
||||
r.StepMini(frame, in)
|
||||
}
|
||||
if r.Mini != nil {
|
||||
t.Fatal("resan tog aldrig slut")
|
||||
@@ -137,7 +179,7 @@ func TestBotWinsLevel001(t *testing.T) {
|
||||
l := loadLevel(t, "001-flygplatsen")
|
||||
r := NewRun(l, RunOptions{Seed: rng.FromInt(1)})
|
||||
goal := l.Find(level.Platform)[0]
|
||||
path := l.Path(r.Player.Tile, goal, r.CanEnter)
|
||||
path := l.Path(r.Player.Tile, goal, r.PathCanEnter)
|
||||
if path == nil {
|
||||
t.Fatal("ingen väg till perrongen")
|
||||
}
|
||||
@@ -152,8 +194,8 @@ func TestBotWinsLevel001(t *testing.T) {
|
||||
t.Fatal("rätt perrong ska ha rätt tåg")
|
||||
}
|
||||
r.Step(frame, None, true)
|
||||
if r.Outcome != Ongoing || r.MiniKind != MiniRide {
|
||||
t.Fatalf("att kliva på ska starta tågresan: outcome=%v kind=%v", r.Outcome, r.MiniKind)
|
||||
if r.Outcome != Ongoing || r.MiniKind != MiniCarPick {
|
||||
t.Fatalf("att kliva på ska börja med vagnvalet: outcome=%v kind=%v", r.Outcome, r.MiniKind)
|
||||
}
|
||||
ride(t, r)
|
||||
if r.Outcome != Won || r.Boarded != tr {
|
||||
@@ -180,7 +222,7 @@ func TestBotLosesOnWrongTrain(t *testing.T) {
|
||||
l := loadLevel(t, "001-flygplatsen")
|
||||
r := NewRun(l, RunOptions{Seed: rng.FromInt(1)})
|
||||
goal := l.Find(level.WrongPlatform)[0]
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.PathCanEnter))
|
||||
tr := waitForTrain(t, r)
|
||||
r.Step(frame, None, true)
|
||||
ride(t, r)
|
||||
@@ -200,7 +242,7 @@ func TestGateNeedsCardBalance(t *testing.T) {
|
||||
if r.DeniedAt < 0 {
|
||||
t.Fatal("nekandet ska registreras för HUD:en")
|
||||
}
|
||||
if l.Path(r.Player.Tile, l.Find(level.Platform)[0], r.CanEnter) != nil {
|
||||
if l.Path(r.Player.Tile, l.Find(level.Platform)[0], r.PathCanEnter) != nil {
|
||||
t.Fatal("utan saldo ska perrongen vara onåbar")
|
||||
}
|
||||
r.Wallet.Card = l.FareYen
|
||||
@@ -220,7 +262,7 @@ func TestBoardOnlyWhenTrainPresent(t *testing.T) {
|
||||
l := loadLevel(t, "001-flygplatsen")
|
||||
r := NewRun(l, RunOptions{Seed: rng.FromInt(1)})
|
||||
goal := l.Find(level.Platform)[0]
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.PathCanEnter))
|
||||
// Spola fram till en tidpunkt då tåget är borta.
|
||||
for {
|
||||
_, at, _ := r.PlatformHere()
|
||||
@@ -239,7 +281,7 @@ func TestSignHereOnlyWhenStill(t *testing.T) {
|
||||
l := loadLevel(t, "001-flygplatsen")
|
||||
r := NewRun(l, RunOptions{Seed: rng.FromInt(1)})
|
||||
sign := l.Find(level.Sign)[0]
|
||||
walk(t, r, l.Path(r.Player.Tile, sign, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, sign, r.PathCanEnter))
|
||||
if sg := r.SignHere(); sg == nil || sg.Text.Get("sv") == "" {
|
||||
t.Fatal("stilla på skyltrutan ska ge skylten")
|
||||
}
|
||||
@@ -256,7 +298,7 @@ func TestAskHelpRevealsSignAndTeachesWord(t *testing.T) {
|
||||
know := lang.NewKnowledge()
|
||||
r := NewRun(l, RunOptions{Dict: loadDict(t), Know: know, Seed: rng.FromInt(1)})
|
||||
sign := l.Find(level.Sign)[1]
|
||||
walk(t, r, l.Path(r.Player.Tile, sign, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, sign, r.PathCanEnter))
|
||||
|
||||
if !r.AskHelp() {
|
||||
t.Fatal("ska kunna fråga om hjälp på en skylt")
|
||||
@@ -296,7 +338,7 @@ func TestHelpIsCancelledByWalkingAway(t *testing.T) {
|
||||
l := loadLevel(t, "001-flygplatsen")
|
||||
r := NewRun(l, RunOptions{Dict: loadDict(t), Seed: rng.FromInt(1)})
|
||||
sign := l.Find(level.Sign)[1]
|
||||
walk(t, r, l.Path(r.Player.Tile, sign, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, sign, r.PathCanEnter))
|
||||
r.AskHelp()
|
||||
r.Step(frame, Left, false)
|
||||
if r.Help.Active {
|
||||
@@ -344,7 +386,7 @@ func TestGoodResultTeachesDestination(t *testing.T) {
|
||||
}{{"snabb", false, 3, true}, {"långsam", true, 1, false}} {
|
||||
know := lang.NewKnowledge()
|
||||
r := NewRun(l, RunOptions{Dict: loadDict(t), Know: know, Seed: rng.FromInt(2)})
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.PathCanEnter))
|
||||
waitForTrain(t, r)
|
||||
if tc.slow {
|
||||
r.Time = 10 * r.ParSec()
|
||||
@@ -374,7 +416,7 @@ func TestReadingGivesSeededProgress(t *testing.T) {
|
||||
play := func(seed uint64) *lang.Knowledge {
|
||||
know := lang.NewKnowledge()
|
||||
r := NewRun(l, RunOptions{Dict: loadDict(t), Know: know, Seed: rng.FromInt(seed)})
|
||||
walk(t, r, l.Path(r.Player.Tile, sign, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, sign, r.PathCanEnter))
|
||||
for i := 0; i < 15; i++ { // gå av och på skylten = nya besök
|
||||
walk(t, r, []level.Point{sign, left})
|
||||
walk(t, r, []level.Point{left, sign})
|
||||
@@ -414,7 +456,7 @@ func TestToiletAndKioskInRun(t *testing.T) {
|
||||
|
||||
// Toalett: tar ToiletSecPerMember per person, avbryts om man går.
|
||||
toilet := l.Find(level.Toilet)[0]
|
||||
walk(t, r, l.Path(r.Player.Tile, toilet, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, toilet, r.PathCanEnter))
|
||||
anna.Meters.Toilet = 10
|
||||
anna.Urge = NeedToilet
|
||||
r.Step(frame, None, true)
|
||||
@@ -428,7 +470,7 @@ func TestToiletAndKioskInRun(t *testing.T) {
|
||||
for r.Player.Moving() { // gå klart rutan innan vi vänder tillbaka
|
||||
r.Step(frame, None, false)
|
||||
}
|
||||
walk(t, r, l.Path(r.Player.Tile, toilet, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, toilet, r.PathCanEnter))
|
||||
r.Step(frame, None, true)
|
||||
if !r.Facility.Active {
|
||||
t.Fatal("besöket ska starta igen")
|
||||
@@ -442,7 +484,7 @@ func TestToiletAndKioskInRun(t *testing.T) {
|
||||
|
||||
// Kiosk: direkt, kostar KioskPriceYen per person från kortet.
|
||||
kiosk := l.Find(level.Kiosk)[0]
|
||||
walk(t, r, l.Path(r.Player.Tile, kiosk, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, kiosk, r.PathCanEnter))
|
||||
anna.Meters.Drink = 5
|
||||
anna.Urge = Thirsty
|
||||
before := r.Wallet.Card
|
||||
@@ -471,9 +513,10 @@ func TestRideWrongOrMissedStopLoses(t *testing.T) {
|
||||
reason string
|
||||
}{{"fel station", true, LostWrongStop}, {"åker förbi", false, LostMissedStop}} {
|
||||
r := NewRun(l, RunOptions{Dict: loadDict(t), Seed: rng.FromInt(1)})
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.PathCanEnter))
|
||||
waitForTrain(t, r)
|
||||
r.Step(frame, None, true)
|
||||
pickCar(t, r)
|
||||
g := r.Mini.(*minigame.Ride)
|
||||
if g.Dest < 1 {
|
||||
t.Fatalf("resmålet ska ligga på linjen men inte först: %d", g.Dest)
|
||||
@@ -500,7 +543,7 @@ func TestTopUpFlowAtMachine(t *testing.T) {
|
||||
t.Fatal("tomt kort stoppas")
|
||||
}
|
||||
machine := l.Find(level.TicketMachine)[0]
|
||||
walk(t, r, l.Path(r.Player.Tile, machine, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, machine, r.PathCanEnter))
|
||||
r.Step(frame, None, true)
|
||||
g, ok := r.Mini.(*minigame.TopUp)
|
||||
if !ok || r.MiniKind != MiniTopUp {
|
||||
@@ -548,7 +591,7 @@ func TestTicketLevelFlow(t *testing.T) {
|
||||
t.Fatal("utan biljett stoppar spärren även med kort")
|
||||
}
|
||||
machine := l.Find(level.TicketMachine)[0]
|
||||
walk(t, r, l.Path(r.Player.Tile, machine, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, machine, r.PathCanEnter))
|
||||
|
||||
// Fel biljett först: tåget vägrar.
|
||||
r.Step(frame, None, true)
|
||||
@@ -563,7 +606,7 @@ func TestTicketLevelFlow(t *testing.T) {
|
||||
t.Fatalf("biljett=%q cash=%d", r.Wallet.Ticket, r.Wallet.Cash)
|
||||
}
|
||||
goal := l.CorrectPlatform()
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.PathCanEnter))
|
||||
waitForTrain(t, r)
|
||||
r.Step(frame, None, true)
|
||||
if r.Mini != nil || r.FlashKey != FlashWrongTicket || r.Outcome != Ongoing {
|
||||
@@ -571,7 +614,7 @@ func TestTicketLevelFlow(t *testing.T) {
|
||||
}
|
||||
|
||||
// Rätt biljett.
|
||||
walk(t, r, l.Path(r.Player.Tile, machine, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, machine, r.PathCanEnter))
|
||||
r.Step(frame, None, true)
|
||||
tk = r.Mini.(*minigame.Ticket)
|
||||
for tk.Options[tk.Cursor].Dest != "渋谷" {
|
||||
@@ -582,9 +625,17 @@ func TestTicketLevelFlow(t *testing.T) {
|
||||
if r.Wallet.Ticket != "渋谷" {
|
||||
t.Fatalf("biljett=%q", r.Wallet.Ticket)
|
||||
}
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.PathCanEnter))
|
||||
waitForTrain(t, r)
|
||||
r.Step(frame, None, true)
|
||||
cp, ok := r.Mini.(*minigame.CarPick)
|
||||
if !ok {
|
||||
t.Fatalf("ombordstigning börjar med vagnval, fick %T", r.Mini)
|
||||
}
|
||||
for cp.Alighting > 0 {
|
||||
r.StepMini(frame, minigame.Input{})
|
||||
}
|
||||
r.StepMini(frame, minigame.Input{Confirm: true})
|
||||
cr, ok := r.Mini.(*minigame.Crowd)
|
||||
if !ok {
|
||||
t.Fatalf("fullt tåg ska ge trängselminispel, fick %T", r.Mini)
|
||||
@@ -608,9 +659,14 @@ func TestCrowdFailureMissesTrain(t *testing.T) {
|
||||
r.Party.nextEventAt = 1e9
|
||||
r.Wallet.Ticket = "渋谷"
|
||||
goal := l.CorrectPlatform()
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.PathCanEnter))
|
||||
waitForTrain(t, r)
|
||||
r.Step(frame, None, true)
|
||||
cp := r.Mini.(*minigame.CarPick)
|
||||
for cp.Alighting > 0 {
|
||||
r.StepMini(frame, minigame.Input{})
|
||||
}
|
||||
r.StepMini(frame, minigame.Input{Confirm: true})
|
||||
cr := r.Mini.(*minigame.Crowd)
|
||||
for n := 0; n < CrowdTries; n++ {
|
||||
for cr.InZone() {
|
||||
@@ -641,7 +697,7 @@ func TestPhoneSpeedRescanAndBattery(t *testing.T) {
|
||||
r.Step(frame, None, false)
|
||||
}
|
||||
gate := l.Find(level.Gate)[0]
|
||||
path := l.Path(r.Player.Tile, gate, r.CanEnter)
|
||||
path := l.Path(r.Player.Tile, gate, r.PathCanEnter)
|
||||
for i, p := range path { // stanna på den första spärrutan – där sker skanningen
|
||||
if l.At(p) == level.Gate {
|
||||
path = path[:i+1]
|
||||
@@ -669,7 +725,7 @@ func TestPhoneSpeedRescanAndBattery(t *testing.T) {
|
||||
r := NewRun(l, RunOptions{Seed: rng.FromInt(5)})
|
||||
r.Party.nextEventAt = 1e9
|
||||
r.Wallet.Phone = true
|
||||
walk(t, r, l.Path(r.Player.Tile, l.Find(level.Gate)[0], r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, l.Find(level.Gate)[0], r.PathCanEnter))
|
||||
return r.Rescans
|
||||
}
|
||||
if run() != run() {
|
||||
@@ -720,12 +776,12 @@ func TestScoreBreakdown(t *testing.T) {
|
||||
l := loadLevel(t, "001-flygplatsen")
|
||||
r := NewRun(l, RunOptions{Dict: loadDict(t), Seed: rng.FromInt(2)})
|
||||
r.Party.nextEventAt = 1e9
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.PathCanEnter))
|
||||
waitForTrain(t, r)
|
||||
r.Step(frame, None, true)
|
||||
ride(t, r)
|
||||
sc := r.Score
|
||||
if r.Outcome != Won || sc.Total <= 0 || sc.Total != sc.Time+sc.Money+sc.Meters+sc.Explore-sc.Penalty {
|
||||
if r.Outcome != Won || sc.Total <= 0 || sc.Total != sc.Time+sc.Money+sc.Meters+sc.Explore+sc.Car-sc.Penalty {
|
||||
t.Fatalf("score=%+v", sc)
|
||||
}
|
||||
if sc.Time != ScoreTimeMax || sc.Money != ScoreMoneyMax-l.FareYen/10 || sc.Penalty != 0 {
|
||||
@@ -756,7 +812,7 @@ func TestDebuffsAffectRunAndAreEarned(t *testing.T) {
|
||||
for r.Player.Moving() {
|
||||
r.Step(frame, None, false)
|
||||
}
|
||||
walk(t, r, l.Path(r.Player.Tile, l.Find(level.Sign)[1], r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, l.Find(level.Sign)[1], r.PathCanEnter))
|
||||
r.AskHelp()
|
||||
if want := lang.HelpSeconds(0) / 0.7; math.Abs(r.Help.Total-want) > 1e-9 {
|
||||
t.Fatalf("hjälptid med dåligt fokus %.2f, vill ha %.2f", r.Help.Total, want)
|
||||
@@ -794,7 +850,7 @@ func TestIndividualCardsAtGateAndMachine(t *testing.T) {
|
||||
t.Fatal("utan saldo på Annas kort stoppar spärren alla")
|
||||
}
|
||||
// Fyll på Annas kort i automaten (personval först).
|
||||
walk(t, r, l1.Path(r.Player.Tile, l1.Find(level.TicketMachine)[0], r.CanEnter))
|
||||
walk(t, r, l1.Path(r.Player.Tile, l1.Find(level.TicketMachine)[0], r.PathCanEnter))
|
||||
r.Step(frame, None, true)
|
||||
g := r.Mini.(*minigame.TopUp)
|
||||
if g.Stage != minigame.TopUpPickMember || len(g.Members) != 2 {
|
||||
@@ -816,7 +872,7 @@ func TestIndividualCardsAtGateAndMachine(t *testing.T) {
|
||||
}
|
||||
// Spärren drar från allas kort.
|
||||
before := r.Wallet.Spent
|
||||
path := l1.Path(r.Player.Tile, gate, r.CanEnter)
|
||||
path := l1.Path(r.Player.Tile, gate, r.PathCanEnter)
|
||||
for i, p := range path {
|
||||
if l1.At(p) == level.Gate {
|
||||
path = path[:i+1]
|
||||
@@ -836,7 +892,7 @@ func TestLevel003Flow(t *testing.T) {
|
||||
r := NewRun(l, RunOptions{Dict: loadDict(t), Seed: rng.FromInt(21)})
|
||||
r.Party.nextEventAt = 1e9
|
||||
machine := l.Find(level.TicketMachine)[0]
|
||||
walk(t, r, l.Path(r.Player.Tile, machine, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, machine, r.PathCanEnter))
|
||||
r.Step(frame, None, true)
|
||||
tk := r.Mini.(*minigame.Ticket)
|
||||
if len(tk.Members) != 4 || tk.Cash != StartCashYen/4 {
|
||||
@@ -896,15 +952,10 @@ func TestLevel003Flow(t *testing.T) {
|
||||
t.Fatal("missnöje ska flashas")
|
||||
}
|
||||
goal := l.CorrectPlatform()
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, goal, r.PathCanEnter))
|
||||
waitForTrain(t, r)
|
||||
r.Step(frame, None, true)
|
||||
cr := r.Mini.(*minigame.Crowd)
|
||||
for i := 0; i < 600 && !cr.InZone(); i++ {
|
||||
r.StepMini(frame, minigame.Input{})
|
||||
}
|
||||
r.StepMini(frame, minigame.Input{Confirm: true})
|
||||
ride(t, r)
|
||||
ride(t, r) // vagnval, ev. trängsel, resa
|
||||
if r.Outcome != Won || r.Wallet.TicketCount != 0 {
|
||||
t.Fatalf("outcome=%v reason=%q tickets=%d", r.Outcome, r.LostReason, r.Wallet.TicketCount)
|
||||
}
|
||||
@@ -917,7 +968,7 @@ func TestNearTrackAndPhases(t *testing.T) {
|
||||
if _, _, _, _, _, ok := r.NearTrack(2); ok {
|
||||
t.Fatal("från starten är ingen perrong nära")
|
||||
}
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.CanEnter))
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.PathCanEnter))
|
||||
tr, p, phase, prog, dist, ok := r.NearTrack(2)
|
||||
if !ok || dist != 0 || p != l.CorrectPlatform() || !tr.Correct || prog < 0 || prog > 1 {
|
||||
t.Fatalf("ok=%v dist=%d p=%v", ok, dist, p)
|
||||
@@ -987,7 +1038,7 @@ func TestRunOptionsFromProgression(t *testing.T) {
|
||||
for r.Player.Moving() {
|
||||
r.Step(frame, None, false)
|
||||
}
|
||||
path := l.Path(r.Player.Tile, gate, r.CanEnter)
|
||||
path := l.Path(r.Player.Tile, gate, r.PathCanEnter)
|
||||
for i, p := range path {
|
||||
if l.At(p) == level.Gate {
|
||||
path = path[:i+1]
|
||||
@@ -1055,7 +1106,7 @@ func TestStairsMoveBetweenFloors(t *testing.T) {
|
||||
// Hela vägen till perrongen med BFS över våningar. Man står i trappans
|
||||
// nedre ände, så kliv av först – trappan tar en när man kliver PÅ den.
|
||||
walk(t, r, []level.Point{r.Player.Tile, {X: 3, Y: 1, Z: 0}})
|
||||
path := l.Path(r.Player.Tile, l.CorrectPlatform(), r.CanEnter)
|
||||
path := l.Path(r.Player.Tile, l.CorrectPlatform(), r.PathCanEnter)
|
||||
if path == nil {
|
||||
t.Fatal("ingen väg")
|
||||
}
|
||||
@@ -1064,3 +1115,71 @@ func TestStairsMoveBetweenFloors(t *testing.T) {
|
||||
t.Fatalf("boten nådde inte perrongen: %v", r.Player.Tile)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCarsWomenOnlyEarlyAndCrowd(t *testing.T) {
|
||||
l := loadLevel(t, "005-ueno")
|
||||
tr := &l.Trains[0]
|
||||
if tr.Cars != 4 || tr.WomenOnlyCar != 1 || !tr.WomenOnlyActive(10) || tr.WomenOnlyActive(200) {
|
||||
t.Fatal("005: fyra vagnar, vagn 1 kvinnovagn de första 150 s")
|
||||
}
|
||||
r := NewRun(l, RunOptions{Dict: loadDict(t), Seed: rng.FromInt(8)})
|
||||
r.Party.nextEventAt = 1e9
|
||||
r.NPCs = nil // folket ska inte stå i vägen för testboten
|
||||
if !r.Party.HasMen() {
|
||||
t.Fatal("tre i sällskapet: Du, Anna, Ville – Ville är man")
|
||||
}
|
||||
walk(t, r, l.Path(r.Player.Tile, l.CorrectPlatform(), r.PathCanEnter))
|
||||
waitForTrain(t, r)
|
||||
if r.Time >= 150 {
|
||||
t.Skip("tåget kom efter rusningen i det här seedet")
|
||||
}
|
||||
r.Step(frame, None, true)
|
||||
cp := r.Mini.(*minigame.CarPick)
|
||||
if !cp.Cars[0].WomenOnly {
|
||||
t.Fatal("vagn 1 ska vara kvinnovagn nu")
|
||||
}
|
||||
// För tidigt: folk kliver av först.
|
||||
r.StepMini(frame, minigame.Input{Confirm: true})
|
||||
for cp.Alighting > 0 {
|
||||
r.StepMini(frame, minigame.Input{})
|
||||
}
|
||||
// Välj kvinnovagnen med en man i sällskapet: grova minus.
|
||||
for cp.Cursor != 0 {
|
||||
r.StepMini(frame, minigame.Input{MoveX: -1})
|
||||
}
|
||||
r.StepMini(frame, minigame.Input{Confirm: true})
|
||||
if !r.WomenOnlyViolation || r.EarlyBoard != 1 || r.FlashKey != FlashWomenOnly || r.CarChosen == nil || r.CarChosen.Index != 1 {
|
||||
t.Fatalf("violation=%v early=%d flash=%q car=%+v", r.WomenOnlyViolation, r.EarlyBoard, r.FlashKey, r.CarChosen)
|
||||
}
|
||||
if cr, ok := r.Mini.(*minigame.Crowd); ok { // full vagn -> trängsel
|
||||
for i := 0; i < 600 && !cr.InZone(); i++ {
|
||||
r.StepMini(frame, minigame.Input{})
|
||||
}
|
||||
r.StepMini(frame, minigame.Input{Confirm: true})
|
||||
}
|
||||
rd := r.Mini.(*minigame.Ride)
|
||||
if rd.Crowd != r.CarChosen.Crowd || rd.StopSec != minigame.RideStopSec(rd.Crowd) {
|
||||
t.Fatal("resan ska ärva vagnens trängsel")
|
||||
}
|
||||
ride(t, r)
|
||||
if r.Outcome != Won {
|
||||
t.Fatalf("outcome=%v reason=%q", r.Outcome, r.LostReason)
|
||||
}
|
||||
if r.Score.Penalty < PenaltyWomenOnly+PenaltyEarlyBoard {
|
||||
t.Fatalf("avdrag=%d, vill ha minst %d", r.Score.Penalty, PenaltyWomenOnly+PenaltyEarlyBoard)
|
||||
}
|
||||
// Bonus för lugn vagn.
|
||||
r2 := NewRun(l, RunOptions{Dict: loadDict(t), Seed: rng.FromInt(8)})
|
||||
r2.Party.nextEventAt = 1e9
|
||||
r2.NPCs = nil
|
||||
walk(t, r2, l.Path(r2.Player.Tile, l.CorrectPlatform(), r2.PathCanEnter))
|
||||
waitForTrain(t, r2)
|
||||
r2.Step(frame, None, true)
|
||||
ride(t, r2) // pickCar väljer lugnaste icke-kvinnovagnen
|
||||
if r2.Outcome == Won && r2.CarChosen.Crowd == 0 && r2.Score.Car != ScoreCarBonus {
|
||||
t.Fatalf("lugn vagn ska ge bonus: %+v", r2.Score)
|
||||
}
|
||||
if r2.WomenOnlyViolation || r2.Score.Penalty >= PenaltyWomenOnly {
|
||||
t.Fatal("rätt vagn: inga grova minus")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user