tins2020/research.go

125 lines
2.9 KiB
Go
Raw Normal View History

2020-05-11 12:41:42 +00:00
package tins2020
import (
"fmt"
"math/rand"
"strconv"
"strings"
"time"
2020-05-17 08:56:56 +00:00
"opslag.de/schobers/geom"
"opslag.de/schobers/zntg"
"opslag.de/schobers/zntg/ui"
2020-05-11 12:41:42 +00:00
)
type Research struct {
2020-05-17 18:24:44 +00:00
ui.StackPanel
2020-05-11 12:41:42 +00:00
game *Game
botanist Specialist
farmer Specialist
2020-05-17 08:56:56 +00:00
description ui.Paragraph
specialists ui.Paragraph
2020-05-17 18:24:44 +00:00
dial *Dial
2020-05-17 08:56:56 +00:00
input ui.Label
2020-05-17 18:24:44 +00:00
animate zntg.Animation
closeRequested ui.Events
}
type Dialer interface {
CanUserType(int) bool
UserGaveWrongInput()
UserTyped(ui.Context, int)
2020-05-11 12:41:42 +00:00
}
func NewResearch(game *Game) *LargeDialog {
2020-05-17 08:56:56 +00:00
research := &Research{game: game}
research.animate.Interval = 20 * time.Millisecond
2020-05-17 18:24:44 +00:00
research.animate.Start()
2020-05-17 08:56:56 +00:00
research.description.Text = "Call a specialist to conduct research with."
2020-05-17 18:24:44 +00:00
research.dial = NewDial(research)
research.Children = []ui.Control{&research.description, &research.specialists, research.dial, &research.input}
2020-05-11 12:41:42 +00:00
2020-05-17 18:24:44 +00:00
dialog := NewLargeDialog("Research", ui.Stretch(research))
research.closeRequested.AddHandlerEmpty(func(ctx ui.Context) { dialog.closeRequested.Notify(ctx, nil) })
return dialog
2020-05-11 12:41:42 +00:00
}
type Specialist struct {
Cost int
Number string
}
2020-05-17 08:56:56 +00:00
func (r *Research) Arrange(ctx ui.Context, bounds geom.RectangleF32, offset geom.PointF32, parent ui.Control) {
r.input.TextAlignment = ui.AlignCenter
2020-05-17 18:24:44 +00:00
r.StackPanel.Arrange(ctx, bounds, offset, parent)
2020-05-11 12:41:42 +00:00
2020-05-17 18:24:44 +00:00
// size := bounds.Size()
// r.specialists.Arrange(ctx, geom.RectRelF32(bounds.Min.X, bounds.Min.Y+40, size.X, size.Y-40), offset, r)
// r.input.Arrange(ctx, geom.RectRelF32(bounds.Min.X, bounds.Min.X+size.Y-48, size.X, 24), offset, r)
2020-05-11 12:41:42 +00:00
}
2020-05-17 18:24:44 +00:00
func (r *Research) CanUserType(digit int) bool {
typing := strconv.Itoa(digit)
return strings.HasPrefix(r.botanist.Number, r.input.Text+typing)
2020-05-11 12:41:42 +00:00
}
2020-05-17 18:24:44 +00:00
func (r *Research) Hidden() {}
2020-05-11 12:41:42 +00:00
2020-05-17 08:56:56 +00:00
func (r *Research) Render(ctx ui.Context) {
2020-05-17 18:24:44 +00:00
r.animate.AnimateFn(r.dial.Tick)
r.StackPanel.Render(ctx)
2020-05-11 12:41:42 +00:00
}
2020-05-17 18:24:44 +00:00
func (r *Research) Shown() {
2020-05-11 12:41:42 +00:00
generateNumber := func() string {
var number string
for i := 0; i < 3; i++ {
number += strconv.Itoa(rand.Intn(9) + 1)
}
return number
}
2020-05-17 18:24:44 +00:00
2020-05-11 12:41:42 +00:00
r.input.Text = ""
2020-05-17 18:24:44 +00:00
r.dial.Reset()
2020-05-11 12:41:42 +00:00
var specialists string
defer func() {
r.specialists.Text = specialists
}()
_, _, price := r.game.Herbarium.NextFlowerToUnlock()
if price == 0 {
specialists += "Botanist (unlocks next flower; unavailable)\n"
specialists += "Farmer (fertilizes land; unavailable)\n"
return
}
r.botanist.Cost = price
if r.game.Balance < r.botanist.Cost {
r.botanist.Number = "**unavailable**"
} else {
r.botanist.Number = generateNumber()
}
specialists += fmt.Sprintf("Botanist: no. %s (unlocks next flower; $ %d)\n", r.botanist.Number, r.botanist.Cost)
specialists += "Farmer: no. **unavailable** (fertilizes land; $ ---)\n"
}
2020-05-17 18:24:44 +00:00
func (r *Research) UserGaveWrongInput() {
r.input.Text = ""
}
func (r *Research) UserTyped(ctx ui.Context, digit int) {
r.input.Text += strconv.Itoa(digit)
if r.input.Text == r.botanist.Number {
r.game.UnlockNextFlower(ctx)
r.input.Text = ""
r.closeRequested.Notify(ctx, nil)
}
}