M10c: vem betalar i kiosken och spärrar utan återvändo
All checks were successful
release / build-release (push) Successful in 2m7s
All checks were successful
release / build-release (push) Successful in 2m7s
Björns tillägg 2026-10-24. Med egna kort och fler i sällskapet frågar kiosken vem som betalar (minigame.Payer: kontant, spelarens kort eller en följares kort; den som inte har råd nekas, Esc avbryter). Avgiften dras nu när man passerar spärren in i det betalda området (level.InsideGates), inte på spärrrutan. Banflaggan oneWayGates: incheckad släpps inte ut igen förrän man åkt; Enter vid spärren kallar på personal (10 s) som låser upp korten; ny inpassering kostar igen. På i 005, 007/007b och 008/008b. Skriptkommandon urge och push. Docs, wiki och skärmdumpar uppdaterade. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -32,9 +32,44 @@ func (s *LevelScene) drawMinigame(g *Game, screen *ebiten.Image) {
|
||||
s.drawRide(a, screen, m, panel)
|
||||
case *minigame.CarPick:
|
||||
s.drawCarPick(a, screen, m, panel)
|
||||
case *minigame.Payer:
|
||||
s.drawPayer(a, screen, m, panel)
|
||||
}
|
||||
}
|
||||
|
||||
// drawPayer: vem betalar i kiosken – kontant, spelarens kort eller en
|
||||
// följares kort, med saldon; de som inte har råd i rött.
|
||||
func (s *LevelScene) drawPayer(a *Assets, screen *ebiten.Image, m *minigame.Payer, p image.Rectangle) {
|
||||
x, y := p.Min.X+8, p.Min.Y+8
|
||||
a.DrawBig(screen, "支払い", x, y, colKnown)
|
||||
a.Draw(screen, a.T("mini.payer.title"), x+60, y+2, colText)
|
||||
y += 20
|
||||
a.Draw(screen, fmt.Sprintf(a.T("mini.payer.price"), m.Price), x, y, colDim)
|
||||
y += LineH + 4
|
||||
for i, o := range m.Options {
|
||||
name, kind := o.Name, a.T("mini.payer.card")
|
||||
if o.Cash {
|
||||
name, kind = a.T("mini.payer.cash"), ""
|
||||
}
|
||||
col := colText
|
||||
if !m.CanAfford(i) {
|
||||
col = colBad
|
||||
}
|
||||
if i == m.Cursor {
|
||||
vector.DrawFilledRect(screen, float32(x-2), float32(y+i*LineH-1), 220, LineH, colBar, false)
|
||||
if m.CanAfford(i) {
|
||||
col = colKnown
|
||||
}
|
||||
}
|
||||
a.Draw(screen, fmt.Sprintf("%-8s %5d¥ %s", name, o.Yen, kind), x, y+i*LineH, col)
|
||||
}
|
||||
y += len(m.Options)*LineH + 4
|
||||
if m.Refused {
|
||||
a.Draw(screen, a.T("mini.payer.short"), x, y, colBad)
|
||||
}
|
||||
a.Draw(screen, a.T("mini.payer.hint"), x, p.Max.Y-14, colDim)
|
||||
}
|
||||
|
||||
// drawCarPick: vagnarna i rad, rosa för kvinnovagn, figurer för trängsel,
|
||||
// kömarkeringar under, och en fas där folk kliver av först.
|
||||
func (s *LevelScene) drawCarPick(a *Assets, screen *ebiten.Image, m *minigame.CarPick, p image.Rectangle) {
|
||||
|
||||
@@ -141,6 +141,18 @@ func (s *LevelScene) drawModeHint(a *Assets, screen *ebiten.Image) {
|
||||
a.Draw(screen, txt, 4, y+3, col)
|
||||
}
|
||||
|
||||
// ForceUrge gör en i sällskapet törstig (skriptläget: "urge NAMN" för
|
||||
// skärmdumpar av kiosken).
|
||||
func (s *LevelScene) ForceUrge(name string) bool {
|
||||
for _, m := range s.run.Party.Members {
|
||||
if m.Name == name {
|
||||
m.Meters.Drink, m.Urge = 5, sim.Thirsty
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// LevelOver rapporterar om banan är avgjord (skriptläget: "waitover").
|
||||
func (s *LevelScene) LevelOver() bool { return s.run.Outcome != sim.Ongoing }
|
||||
|
||||
@@ -222,6 +234,13 @@ func (s *LevelScene) MiniPick(text string) bool {
|
||||
s.run.StepMini(0, minigame.Input{MoveX: 1})
|
||||
return false
|
||||
}
|
||||
case *minigame.Payer:
|
||||
o := m.Options[m.Cursor]
|
||||
if o.Name == text || (text == "cash" && o.Cash) {
|
||||
return true
|
||||
}
|
||||
s.run.StepMini(0, minigame.Input{MoveX: 1})
|
||||
return false
|
||||
case *minigame.TopUp:
|
||||
switch m.Stage {
|
||||
case minigame.TopUpPickMember:
|
||||
@@ -492,6 +511,9 @@ func (s *LevelScene) drawHUD(g *Game, screen *ebiten.Image) {
|
||||
if r.Facility.Active {
|
||||
p = r.FacilityProgress()
|
||||
}
|
||||
if r.Staff.Active {
|
||||
p = r.StaffProgress()
|
||||
}
|
||||
by := float32(y + h - 7)
|
||||
vector.DrawFilledRect(screen, 4, by, ScreenW-8, 4, colBar, false)
|
||||
vector.DrawFilledRect(screen, 4, by, float32((ScreenW-8)*p), 4, colKnown, false)
|
||||
@@ -567,6 +589,17 @@ func (s *LevelScene) infoLines(a *Assets) (lines []line, accent color.Color, bar
|
||||
}
|
||||
|
||||
switch lvl.At(tile) {
|
||||
case level.Gate:
|
||||
switch {
|
||||
case r.Staff.Active:
|
||||
return []line{plainLine(a.T("hud.staff_busy"), colDim)}, colGood, true
|
||||
case r.NoExitAt >= 0 && r.Time-r.NoExitAt < deniedShowSec:
|
||||
return a.wrapLine(plainLine(fmt.Sprintf(a.T("hud.no_exit"), sim.StaffSec), colBad), maxW), colBad, false
|
||||
case r.NeedsStaff():
|
||||
return []line{plainLine(fmt.Sprintf(a.T("hud.staff_prompt"), sim.StaffSec), colWarn)}, colWarn, false
|
||||
case lvl.OneWayGates && r.StaffUnlocked:
|
||||
return []line{plainLine(a.T("hud.unlocked_prompt"), colGood)}, colGood, false
|
||||
}
|
||||
case level.Toilet:
|
||||
if r.Facility.Active {
|
||||
return []line{plainLine(a.T("hud.toilet_busy"), colDim)}, colGood, true
|
||||
|
||||
@@ -88,11 +88,20 @@ func parseScript(src string) (*script, error) {
|
||||
return nil, fmt.Errorf("script: okänd riktning %q", f[1])
|
||||
}
|
||||
st.n, _ = strconv.Atoi(f[2])
|
||||
case "shot", "pick", "waitphase":
|
||||
case "shot", "pick", "waitphase", "urge":
|
||||
if len(f) != 2 {
|
||||
return nil, fmt.Errorf("script: '%s TEXT'", f[0])
|
||||
}
|
||||
st.arg = f[1]
|
||||
case "push": // håll en riktning N bildrutor oavsett om spelaren kommer någonstans (t.ex. mot en spärr)
|
||||
if len(f) != 3 {
|
||||
return nil, fmt.Errorf("script: 'push DIR N'")
|
||||
}
|
||||
st.dir = parseDir(f[1])
|
||||
if st.dir == sim.None {
|
||||
return nil, fmt.Errorf("script: okänd riktning %q", f[1])
|
||||
}
|
||||
st.n, _ = strconv.Atoi(f[2])
|
||||
case "quit", "waittrain", "waitstop", "waitover":
|
||||
default:
|
||||
return nil, fmt.Errorf("script: okänt kommando %q", f[0])
|
||||
@@ -128,6 +137,7 @@ type trainWaiter interface {
|
||||
RideAtDest() bool
|
||||
LevelOver() bool
|
||||
MiniPick(text string) bool
|
||||
ForceUrge(name string) bool
|
||||
TrackPhaseName() string
|
||||
}
|
||||
|
||||
@@ -201,6 +211,17 @@ func (s *script) tick(g *Game, frame *ebiten.Image) error {
|
||||
if tw, ok := g.scene.(trainWaiter); !ok || tw.LevelOver() || s.counter > 60*120 {
|
||||
s.advance()
|
||||
}
|
||||
case "urge":
|
||||
if tw, ok := g.scene.(trainWaiter); ok {
|
||||
tw.ForceUrge(st.arg)
|
||||
}
|
||||
s.advance()
|
||||
case "push":
|
||||
virtual.held = st.dir
|
||||
s.counter++
|
||||
if s.counter >= st.n {
|
||||
s.advance()
|
||||
}
|
||||
case "waitphase":
|
||||
s.counter++
|
||||
if tw, ok := g.scene.(trainWaiter); !ok || tw.TrackPhaseName() == st.arg || s.counter > 60*60 {
|
||||
|
||||
Reference in New Issue
Block a user