Compare commits
23 Commits
zntg_migra
...
master
Author | SHA1 | Date | |
---|---|---|---|
d0e6721953 | |||
1ae7e9ebe4 | |||
8264942602 | |||
6ce7baed2b | |||
bd1d685c20 | |||
93002a784b | |||
7230ac966b | |||
62cbe14170 | |||
df97e826c8 | |||
1bea3dd412 | |||
ddef723f80 | |||
cb58ebdf77 | |||
6a8a23bf61 | |||
820d0f109a | |||
2f5f682a59 | |||
064ec4619d | |||
ef6a60e155 | |||
ea26db29f3 | |||
d24b4eb376 | |||
855db3375c | |||
822d8ab584 | |||
b7b663ddb5 | |||
66eaa054c5 |
@ -118,6 +118,15 @@ go generate opslag.de/schobers/tins2020/cmd/tins2020
|
||||
go install opslag.de/schobers/tins2020/cmd/tins2020 -tags static -ldflags "-s -w"
|
||||
```
|
||||
|
||||
If you want to use the Allegro backend you can add the build tag `allegro` to the `go install` command. E.g.:
|
||||
```
|
||||
go install opslag.de/schobers/tins2020/cmd/tins2020 -tags static,allegro -ldflags "-s -w"
|
||||
```
|
||||
In this case the SDL 2.0 prerequisite is replaced by the Allegro 5.2 (development libraries must be available for your C compiler).
|
||||
|
||||
## Command line interface
|
||||
You can extract all resources embedded in the executable by running it from the command line with the `--extract-resources` flag. The resources will be extract in the current working directory. Note that the game will use the resources on disk first if they are available.
|
||||
|
||||
## Sources
|
||||
Can be found at https://opslag.de/schobers/tins2020 (Git repository).
|
||||
|
||||
|
@ -96,6 +96,7 @@ func (b *BuyFlowerButton) updateTexts(ctx ui.Context) error {
|
||||
if err := b.priceTexture.Update(textUpdate(ctx.Renderer(), font, color, FmtMoney(b.Flower.BuyPrice))); err != nil {
|
||||
return err
|
||||
}
|
||||
b.Disabled = !b.Flower.Unlocked
|
||||
b.upToDate = true
|
||||
return nil
|
||||
}
|
||||
|
@ -5,18 +5,13 @@ import (
|
||||
"image/color"
|
||||
"log"
|
||||
|
||||
"opslag.de/schobers/fs/ricefs"
|
||||
"opslag.de/schobers/geom"
|
||||
"opslag.de/schobers/zntg"
|
||||
"opslag.de/schobers/zntg/addons/res"
|
||||
"opslag.de/schobers/zntg/addons/riceres"
|
||||
"opslag.de/schobers/zntg/play"
|
||||
"opslag.de/schobers/zntg/ui"
|
||||
|
||||
_ "opslag.de/schobers/zntg/sdlui" // rendering backend
|
||||
// _ "opslag.de/schobers/zntg/allg5ui" // rendering backend
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"opslag.de/schobers/tins2020"
|
||||
)
|
||||
|
||||
@ -31,9 +26,8 @@ func main() {
|
||||
}
|
||||
|
||||
func openResources(box *rice.Box) ui.Resources {
|
||||
fs := ricefs.NewFs(box)
|
||||
resources, _ := res.NewAferoFallbackResources(`res`, fs, `botanim`)
|
||||
return resources
|
||||
embedded := riceres.New(box)
|
||||
return ui.NewFallbackResources(ui.NewPathResources(nil, box.Name()), embedded)
|
||||
}
|
||||
|
||||
type app struct {
|
||||
@ -140,8 +134,9 @@ func run() error {
|
||||
}
|
||||
defer settings.Store()
|
||||
|
||||
if settings.Window.Location == nil {
|
||||
settings.Window.Location = ptPtr(sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED)
|
||||
var location *geom.PointF32
|
||||
if settings.Window.Location != nil {
|
||||
location = &geom.PointF32{X: float32(settings.Window.Location.X), Y: float32(settings.Window.Location.Y)}
|
||||
}
|
||||
if settings.Window.Size == nil {
|
||||
settings.Window.Size = ptPtr(800, 600)
|
||||
@ -151,7 +146,7 @@ func run() error {
|
||||
settings.Window.VSync = &vsync
|
||||
}
|
||||
renderer, err := ui.NewRenderer("Botanim - TINS 2020", settings.Window.Size.X, settings.Window.Size.Y, ui.NewRendererOptions{
|
||||
Location: &geom.PointF32{X: float32(settings.Window.Location.X), Y: float32(settings.Window.Location.Y)},
|
||||
Location: location,
|
||||
Resizable: true,
|
||||
VSync: *settings.Window.VSync,
|
||||
})
|
||||
|
16
cmd/tins2020/tins2020_allegro.go
Normal file
16
cmd/tins2020/tins2020_allegro.go
Normal file
@ -0,0 +1,16 @@
|
||||
// +build allegro
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
_ "opslag.de/schobers/zntg/allg5ui" // rendering backend
|
||||
)
|
||||
|
||||
// #cgo windows,allegro LDFLAGS: -Wl,-subsystem,windows
|
||||
import "C"
|
||||
|
||||
func init() {
|
||||
log.Println("Using Allegro5 rendering backend")
|
||||
}
|
13
cmd/tins2020/tins2020_sdl.go
Normal file
13
cmd/tins2020/tins2020_sdl.go
Normal file
@ -0,0 +1,13 @@
|
||||
// +build !allegro
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
_ "opslag.de/schobers/zntg/sdlui" // SDL rendering backend
|
||||
)
|
||||
|
||||
func init() {
|
||||
log.Println("Using SDL rendering backend")
|
||||
}
|
140
confirmationdialog.go
Normal file
140
confirmationdialog.go
Normal file
@ -0,0 +1,140 @@
|
||||
package tins2020
|
||||
|
||||
import (
|
||||
"opslag.de/schobers/geom"
|
||||
"opslag.de/schobers/zntg"
|
||||
"opslag.de/schobers/zntg/ui"
|
||||
)
|
||||
|
||||
type confirmationDialog struct {
|
||||
ui.Proxy
|
||||
|
||||
active string
|
||||
cancel ui.Button
|
||||
confirm ui.Button
|
||||
question ui.Paragraph
|
||||
|
||||
userDecided ui.Events
|
||||
}
|
||||
|
||||
func newConfirmationDialog(caption, question string) *confirmationDialog {
|
||||
dialog := &confirmationDialog{}
|
||||
|
||||
dialog.active = "confirm"
|
||||
dialog.cancel.Text = "Cancel"
|
||||
dialog.cancel.ButtonClicked().AddHandler(func(ctx ui.Context, _ ui.ControlClickedArgs) { dialog.userCanceled(ctx) })
|
||||
dialog.cancel.Type = ui.ButtonTypeText
|
||||
dialog.cancel.HoverColor = zntg.MustHexColor(`FFFFFF1F`)
|
||||
dialog.confirm.Text = "OK"
|
||||
dialog.confirm.ButtonClicked().AddHandler(func(ctx ui.Context, _ ui.ControlClickedArgs) { dialog.userConfirmed(ctx) })
|
||||
dialog.confirm.Type = ui.ButtonTypeText
|
||||
dialog.confirm.HoverColor = zntg.MustHexColor(`FFFFFF1F`)
|
||||
dialog.question.Text = question
|
||||
dialog.updateActive()
|
||||
|
||||
responses := ui.BuildStackPanel(ui.OrientationHorizontal, func(p *ui.StackPanel) {
|
||||
p.AddChild(ui.FixedWidth(&dialog.cancel, 160))
|
||||
p.AddChild(ui.FixedWidth(&dialog.confirm, 160))
|
||||
})
|
||||
|
||||
content := &dialogBase{}
|
||||
content.Background = zntg.MustHexColor(`#0000007F`)
|
||||
content.Init(caption, ui.BuildStackPanel(ui.OrientationVertical, func(p *ui.StackPanel) {
|
||||
p.AddChild(&dialog.question)
|
||||
p.AddChild(responses)
|
||||
}))
|
||||
|
||||
dialog.Content = ui.Background(ui.BuildSpacing(content, func(s *ui.Spacing) {
|
||||
s.Width = ui.Fixed(320)
|
||||
s.Center()
|
||||
}), zntg.MustHexColor(`#0000007F`))
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
func (d *confirmationDialog) toggleActive() {
|
||||
if d.active == "confirm" {
|
||||
d.active = "cancel"
|
||||
} else {
|
||||
d.active = "confirm"
|
||||
}
|
||||
d.updateActive()
|
||||
}
|
||||
|
||||
func (d *confirmationDialog) updateActive() {
|
||||
d.cancel.Background = nil
|
||||
d.confirm.Background = nil
|
||||
switch d.active {
|
||||
case "cancel":
|
||||
d.cancel.Background = hoverTransparentColor
|
||||
case "confirm":
|
||||
d.confirm.Background = hoverTransparentColor
|
||||
}
|
||||
}
|
||||
|
||||
func (d *confirmationDialog) userCanceled(ctx ui.Context) {
|
||||
d.userDecided.Notify(ctx, false)
|
||||
}
|
||||
|
||||
func (d *confirmationDialog) userConfirmed(ctx ui.Context) {
|
||||
d.userDecided.Notify(ctx, true)
|
||||
}
|
||||
|
||||
func (d *confirmationDialog) Handle(ctx ui.Context, e ui.Event) bool {
|
||||
if d.Proxy.Handle(ctx, e) {
|
||||
return true
|
||||
}
|
||||
switch e := e.(type) {
|
||||
case *ui.MouseButtonDownEvent:
|
||||
if e.Button == ui.MouseButtonRight {
|
||||
d.userCanceled(ctx)
|
||||
return true
|
||||
}
|
||||
case *ui.MouseMoveEvent:
|
||||
if d.cancel.IsOver() {
|
||||
d.active = "cancel"
|
||||
}
|
||||
if d.confirm.IsOver() {
|
||||
d.active = "confirm"
|
||||
}
|
||||
d.updateActive()
|
||||
case *ui.KeyDownEvent:
|
||||
switch e.Key {
|
||||
case ui.KeyEscape:
|
||||
d.userCanceled(ctx)
|
||||
return true
|
||||
case ui.KeyEnter:
|
||||
switch d.active {
|
||||
case "cancel":
|
||||
d.userCanceled(ctx)
|
||||
case "confirm":
|
||||
d.userConfirmed(ctx)
|
||||
}
|
||||
return true
|
||||
case ui.KeyLeft:
|
||||
d.toggleActive()
|
||||
case ui.KeyRight:
|
||||
d.toggleActive()
|
||||
case ui.KeyTab:
|
||||
d.toggleActive()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type dialogBase struct {
|
||||
ui.StackPanel
|
||||
|
||||
caption ui.Label
|
||||
content ui.Proxy
|
||||
}
|
||||
|
||||
func (d *dialogBase) DesiredSize(ctx ui.Context, size geom.PointF32) geom.PointF32 {
|
||||
return d.StackPanel.DesiredSize(ctx, size)
|
||||
}
|
||||
|
||||
func (d *dialogBase) Init(caption string, content ui.Control) {
|
||||
d.caption.Text = caption
|
||||
d.content.Content = content
|
||||
d.Children = []ui.Control{&d.caption, &d.content}
|
||||
}
|
14
dialogs.go
14
dialogs.go
@ -67,6 +67,20 @@ func (d *Dialogs) Hidden() {
|
||||
d.Proxy.Hidden()
|
||||
}
|
||||
|
||||
func (d *Dialogs) AskConfirmation(ctx ui.Context, caption, question string, confirm, cancel ui.EventFn) {
|
||||
dialog := newConfirmationDialog(caption, question)
|
||||
dialog.userDecided.AddHandler(func(ctx ui.Context, state interface{}) {
|
||||
decision := state.(bool)
|
||||
if decision {
|
||||
confirm(ctx, nil)
|
||||
} else {
|
||||
cancel(ctx, nil)
|
||||
}
|
||||
d.Close(ctx)
|
||||
})
|
||||
d.showDialog(ctx, dialog)
|
||||
}
|
||||
|
||||
func (d *Dialogs) ShowIntro(ctx ui.Context) {
|
||||
d.showDialog(ctx, d.intro)
|
||||
}
|
||||
|
@ -64,8 +64,8 @@ func NewConeflowerTraits() FlowerTraits {
|
||||
Spread: 0.0005,
|
||||
Life: 0.99993,
|
||||
Resistance: FlowerResistance{
|
||||
Cold: 0.7,
|
||||
Hot: 0.8,
|
||||
Cold: 0.6,
|
||||
Hot: 0.9,
|
||||
Dry: 0.8,
|
||||
Wet: 0.5,
|
||||
},
|
||||
|
7
game.go
7
game.go
@ -261,7 +261,12 @@ func (g *Game) TogglePause(ctx ui.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) Tool() Tool { return g.tool }
|
||||
func (g *Game) Tool() Tool {
|
||||
if g.tool == nil {
|
||||
return &NoTool{}
|
||||
}
|
||||
return g.tool
|
||||
}
|
||||
|
||||
func (g *Game) ToolChanged() ui.EventHandler { return &g.toolChanged }
|
||||
|
||||
|
@ -32,6 +32,36 @@ func NewGameControls(game *Game, dialogs *Dialogs) *GameControls {
|
||||
return &GameControls{game: game, dialogs: dialogs}
|
||||
}
|
||||
|
||||
func (c *GameControls) askUserBeforeLoad(ctx ui.Context) {
|
||||
c.dialogs.AskConfirmation(ctx,
|
||||
"Do you want to load?",
|
||||
"You will lose any progress you made during this session.",
|
||||
func(ui.Context, interface{}) {
|
||||
c.game.Load(ctx)
|
||||
c.updateFlowerControls()
|
||||
},
|
||||
func(ui.Context, interface{}) {})
|
||||
}
|
||||
|
||||
func (c *GameControls) askUserBeforeNew(ctx ui.Context) {
|
||||
c.dialogs.AskConfirmation(ctx,
|
||||
"Do you want to start a new game?",
|
||||
"You will lose any progress you made during this session.",
|
||||
func(ui.Context, interface{}) {
|
||||
c.game.New(ctx)
|
||||
c.updateFlowerControls()
|
||||
},
|
||||
func(ui.Context, interface{}) {})
|
||||
}
|
||||
|
||||
func (c *GameControls) askUserBeforeSave(ctx ui.Context) {
|
||||
c.dialogs.AskConfirmation(ctx,
|
||||
"Do you want to save?",
|
||||
"Saving will overwrite any previous save game.",
|
||||
func(ui.Context, interface{}) { c.game.Save() },
|
||||
func(ui.Context, interface{}) {})
|
||||
}
|
||||
|
||||
func (c *GameControls) Init(ctx ui.Context) {
|
||||
ctx.Overlays().AddOnTop(fpsOverlayName, &play.FPS{}, false)
|
||||
c.game.SpeedChanged().AddHandler(c.speedChanged)
|
||||
@ -76,23 +106,17 @@ func (c *GameControls) Init(ctx ui.Context) {
|
||||
b.Disabled = true
|
||||
b.DisabledColor = zntg.MustHexColor("#AFAFAF")
|
||||
}),
|
||||
NewIconButtonConfigure("control-save", func(ui.Context) { c.game.Save() }, func(b *IconButton) {
|
||||
b.Tooltip = "Save game (overwrites previous save; no confirmation)"
|
||||
NewIconButtonConfigure("control-save", c.askUserBeforeSave, func(b *IconButton) {
|
||||
b.Tooltip = "Save game (key: Ctrl+S)"
|
||||
}),
|
||||
NewIconButtonConfigure("control-load", func(ctx ui.Context) {
|
||||
c.game.Load(ctx)
|
||||
c.updateFlowerControls()
|
||||
}, func(b *IconButton) {
|
||||
b.Tooltip = "Load last saved game (no confirmation)"
|
||||
NewIconButtonConfigure("control-load", c.askUserBeforeLoad, func(b *IconButton) {
|
||||
b.Tooltip = "Load last saved game (key: Ctrl+L)"
|
||||
}),
|
||||
NewIconButtonConfigure("control-new", func(ctx ui.Context) {
|
||||
c.game.New(ctx)
|
||||
c.updateFlowerControls()
|
||||
}, func(b *IconButton) {
|
||||
b.Tooltip = "Start new game (no confirmation)"
|
||||
NewIconButtonConfigure("control-new", c.askUserBeforeNew, func(b *IconButton) {
|
||||
b.Tooltip = "Start new game (key: Ctrl+N)"
|
||||
}),
|
||||
NewIconButtonConfigure("control-information", c.dialogs.ShowIntro, func(b *IconButton) {
|
||||
b.Tooltip = "Show information/intro"
|
||||
b.Tooltip = "Show information/intro (key: Escape)"
|
||||
}),
|
||||
}
|
||||
for i, child := range c.menu.Children {
|
||||
@ -195,7 +219,7 @@ func (c *GameControls) Handle(ctx ui.Context, event ui.Event) bool {
|
||||
case ui.KeyR:
|
||||
c.dialogs.ShowResearch(ctx)
|
||||
case ui.KeyEscape:
|
||||
if c.game.Tool() == nil {
|
||||
if c.game.Tool().Type() == "none" {
|
||||
c.dialogs.ShowIntro(ctx)
|
||||
} else {
|
||||
c.game.CancelTool(ctx)
|
||||
@ -205,6 +229,16 @@ func (c *GameControls) Handle(ctx ui.Context, event ui.Event) bool {
|
||||
c.game.Debug = !c.game.Debug
|
||||
ctx.Overlays().Toggle(fpsOverlayName)
|
||||
}
|
||||
if e.Modifiers == ui.KeyModifierControl {
|
||||
switch e.Key {
|
||||
case ui.KeyL:
|
||||
c.askUserBeforeLoad(ctx)
|
||||
case ui.KeyN:
|
||||
c.askUserBeforeNew(ctx)
|
||||
case ui.KeyS:
|
||||
c.askUserBeforeSave(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ func (h *Herbarium) Reset() {
|
||||
})
|
||||
h.Add("loosestrife", FlowerDescriptor{
|
||||
Name: "Loosestrife",
|
||||
Description: "A simple flower that will spread in temperate and wet climates.",
|
||||
Description: "A simple flower that will spread in temperate and damp climates.",
|
||||
IconTemplate: "flower-loosestrife-%s",
|
||||
BuyPrice: 100,
|
||||
SellPrice: 20,
|
||||
|
@ -41,7 +41,7 @@ func (b *IconButton) Render(ctx ui.Context) {
|
||||
}
|
||||
|
||||
func (b *IconButton) RenderActive(ctx ui.Context) {
|
||||
if b.Active && !b.Disabled && !b.IsOver() {
|
||||
if b.Active || (!b.Disabled && b.IsOver()) {
|
||||
ctx.Renderer().FillRectangle(b.Bounds(), hoverTransparentColor)
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ type LargeDialogTitleBar struct {
|
||||
ui.ContainerBase
|
||||
|
||||
title ui.Label
|
||||
close IconButton
|
||||
close ui.Button
|
||||
}
|
||||
|
||||
func NewLargeDialogTitleBar(title string, closeRequested ui.EventFn) *LargeDialogTitleBar {
|
||||
|
43
resources.go
43
resources.go
@ -1,43 +0,0 @@
|
||||
package tins2020
|
||||
|
||||
import (
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
"github.com/spf13/afero"
|
||||
"opslag.de/schobers/fs/ricefs"
|
||||
"opslag.de/schobers/fs/vfs"
|
||||
)
|
||||
|
||||
type Resources struct {
|
||||
box *rice.Box
|
||||
fs afero.Fs
|
||||
copy vfs.CopyDir
|
||||
}
|
||||
|
||||
func (r *Resources) Box() *rice.Box {
|
||||
return r.box
|
||||
}
|
||||
|
||||
func (r *Resources) Destroy() {
|
||||
r.copy.Destroy()
|
||||
}
|
||||
|
||||
func (r *Resources) Fs() afero.Fs {
|
||||
return r.fs
|
||||
}
|
||||
|
||||
func (r *Resources) Open(box *rice.Box) error {
|
||||
r.box = box
|
||||
r.fs = vfs.NewOsFsFallback(r.box.Name(), ricefs.NewFs(box))
|
||||
copy, err := vfs.NewCopyDir(r.fs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.copy = copy
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Resources) Copy() vfs.CopyDir { return r.copy }
|
||||
|
||||
func (r *Resources) Retrieve(name string) (string, error) {
|
||||
return r.copy.Retrieve(name)
|
||||
}
|
@ -7,33 +7,54 @@ else
|
||||
version="$1"
|
||||
fi
|
||||
|
||||
version_safe=${version//\./_}
|
||||
|
||||
echo "Creating ${version} release"
|
||||
|
||||
rm -rf build/linux*
|
||||
rm -rf build/macosx*
|
||||
rm -rf build/windows*
|
||||
|
||||
mkdir -p build/linux
|
||||
mkdir -p build/windows
|
||||
|
||||
go generate ../cmd/tins2020
|
||||
|
||||
go build -tags static -ldflags "-s -w" -o build/linux/botanim ../cmd/tins2020
|
||||
cp ../README.md build/linux
|
||||
|
||||
CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go build -tags static -ldflags "-s -w" -o build/windows/botanim.exe ../cmd/tins2020
|
||||
cp ../README.md build/windows
|
||||
|
||||
|
||||
mkdir -p build/release
|
||||
|
||||
cd build
|
||||
go generate ../cmd/tins2020
|
||||
|
||||
cd linux
|
||||
zip -9 -q ../release/botanim_${version}_linux_amd64.zip *
|
||||
echo "Created Linux release: build/release/botanim_${version}_linux_amd64.zip"
|
||||
cd ..
|
||||
mkdir -p build/linux
|
||||
go build -tags static -ldflags "-s -w" -o build/linux/botanim ../cmd/tins2020
|
||||
cp ../README.md build/linux
|
||||
cd build/linux
|
||||
zip -9 -q ../release/botanim_${version_safe}_linux_amd64.zip *
|
||||
echo "Created Linux release: build/release/botanim_${version_safe}_linux_amd64.zip"
|
||||
cd ../..
|
||||
|
||||
cd windows
|
||||
zip -9 -q ../release/botanim_${version}_windows_amd64.zip *
|
||||
echo "Created Windows release: build/release/botanim_${version}_windows_amd64.zip"
|
||||
cd ..
|
||||
mkdir -p build/linux-allegro
|
||||
go build -tags static,allegro -ldflags "-s -w" -o build/linux-allegro/botanim ../cmd/tins2020
|
||||
cp ../README.md build/linux-allegro
|
||||
cd build/linux-allegro
|
||||
zip -9 -q ../release/botanim_allegro_${version_safe}_linux_amd64.zip *
|
||||
echo "Created Linux (Allegro) release: build/release/botanim_allegro_${version_safe}_linux_amd64.zip"
|
||||
cd ../..
|
||||
|
||||
mkdir -p build/macosx
|
||||
CGO_ENABLED=1 CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 go build -tags static -ldflags "-s -w" -o build/macosx/botanim ../cmd/tins2020
|
||||
cp ../README.md build/macosx
|
||||
cd build/macosx
|
||||
zip -9 -q ../release/botanim_${version_safe}_macosx_amd64.zip *
|
||||
echo "Created Mac OS X release: build/release/botanim_${version_safe}_macosx_amd64.zip"
|
||||
cd ../..
|
||||
|
||||
mkdir -p build/windows
|
||||
CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go build -tags static -ldflags "-s -w" -o build/windows/botanim.exe ../cmd/tins2020
|
||||
cp ../README.md build/windows
|
||||
cd build/windows
|
||||
zip -9 -q ../release/botanim_${version_safe}_windows_amd64.zip *
|
||||
echo "Created Windows release: build/release/botanim_${version_safe}_windows_amd64.zip"
|
||||
cd ../..
|
||||
|
||||
mkdir -p build/windows-allegro
|
||||
CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go build -tags static,allegro,mingw64_7_3 -ldflags "-s -w" -o build/windows-allegro/botanim.exe ../cmd/tins2020
|
||||
cp ../README.md build/windows-allegro
|
||||
cd build/windows-allegro
|
||||
zip -9 -q ../release/botanim_allegro_${version_safe}_windows_amd64.zip *
|
||||
echo "Created Windows (Allegro) release: build/release/botanim_allegro_${version_safe}_windows_amd64.zip"
|
||||
cd ../..
|
||||
|
@ -63,13 +63,10 @@ func (r *terrainRenderer) Handle(ctx ui.Context, event ui.Event) bool {
|
||||
}
|
||||
}
|
||||
case *ui.MouseButtonUpEvent:
|
||||
pos := e.Pos()
|
||||
if pos.In(r.interactBounds) {
|
||||
if _, ok := r.drag.IsDragging(); ok {
|
||||
r.game.Terrain.Center = r.isometric.TileInt(r.isometric.Center())
|
||||
r.drag.Cancel()
|
||||
}
|
||||
}
|
||||
case *ui.MouseMoveEvent:
|
||||
pos := e.Pos()
|
||||
if pos.In(r.interactBounds) {
|
||||
@ -80,7 +77,7 @@ func (r *terrainRenderer) Handle(ctx ui.Context, event ui.Event) bool {
|
||||
}
|
||||
if _, ok := r.drag.IsDragging(); ok {
|
||||
delta, _ := r.drag.Move(pos)
|
||||
r.isometric.Pan(r.isometric.ViewToTileRelative(delta.Invert()))
|
||||
r.isometric.Pan(delta.Invert())
|
||||
}
|
||||
if r.hover != nil {
|
||||
if e.MouseWheel < 0 {
|
||||
@ -100,13 +97,54 @@ func (r *terrainRenderer) Handle(ctx ui.Context, event ui.Event) bool {
|
||||
case ui.KeyPadMinus:
|
||||
r.isometric.ZoomOut(r.isometric.Center())
|
||||
case ui.KeyW:
|
||||
r.isometric.Pan(geom.PtF32(-1, -1))
|
||||
r.isometric.PanTile(geom.PtF32(-1, -1))
|
||||
case ui.KeyA:
|
||||
r.isometric.Pan(geom.PtF32(-1, 1))
|
||||
r.isometric.PanTile(geom.PtF32(-1, 1))
|
||||
case ui.KeyS:
|
||||
r.isometric.Pan(geom.PtF32(1, 1))
|
||||
r.isometric.PanTile(geom.PtF32(1, 1))
|
||||
case ui.KeyD:
|
||||
r.isometric.Pan(geom.PtF32(1, -1))
|
||||
r.isometric.PanTile(geom.PtF32(1, -1))
|
||||
}
|
||||
}
|
||||
|
||||
tool := r.game.Tool().Type()
|
||||
if r.hover != nil {
|
||||
if tool != "none" {
|
||||
ctx.Renderer().SetMouseCursor(ui.MouseCursorPointer)
|
||||
}
|
||||
if tool == "plant-flower" {
|
||||
terrain := r.game.Terrain
|
||||
temp := func() string {
|
||||
temp := terrain.Temp.Value(r.hover.X, r.hover.Y)
|
||||
switch {
|
||||
case temp < .3:
|
||||
return "very cold"
|
||||
case temp < .4:
|
||||
return "cold"
|
||||
case temp > .7:
|
||||
return "very hot"
|
||||
case temp > .6:
|
||||
return "hot"
|
||||
default:
|
||||
return "moderate"
|
||||
}
|
||||
}()
|
||||
humid := func() string {
|
||||
humid := terrain.Humid.Value(r.hover.X, r.hover.Y)
|
||||
switch {
|
||||
case humid < .3:
|
||||
return " and very arid"
|
||||
case humid < .4:
|
||||
return " and arid"
|
||||
case humid > .7:
|
||||
return " and very damp"
|
||||
case humid > .6:
|
||||
return " and damp"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}()
|
||||
ctx.ShowTooltip(fmt.Sprintf("It is %s%s over here", temp, humid))
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
6
tools.go
6
tools.go
@ -17,6 +17,12 @@ func (t *PlantFlowerTool) ClickedTile(game *Game, tile geom.Point) {
|
||||
game.PlantFlower(t.FlowerID, tile)
|
||||
}
|
||||
|
||||
type NoTool struct{}
|
||||
|
||||
func (t *NoTool) Type() string { return "none" }
|
||||
|
||||
func (t *NoTool) ClickedTile(*Game, geom.Point) {}
|
||||
|
||||
type ShovelTool struct{}
|
||||
|
||||
func (t *ShovelTool) Type() string { return "shovel" }
|
||||
|
Loading…
Reference in New Issue
Block a user