Browse Source

Major game update

- Fixed bulldozer
- Fixed tax system (now collected per citizen)
- Fixed building unintentionally when adjusting tax rates
- Fixed game crash on Windows
- Added city population indicator
- Added center camera via right click
- Added new music to soundtrack
- Removed screen edge scrolling
- Removed middle mouse scrolling
main v1.1.0
Trevor Slocum 8 months ago
parent
commit
a459c97c86
  1. 13
      CHANGELOG
  2. 35
      asset/asset.go
  3. 8
      asset/sound/explosion/LICENSE
  4. BIN
      asset/sound/explosion/explosion1.ogg
  5. BIN
      asset/sound/explosion/explosion2.ogg
  6. BIN
      asset/sound/please_recycle.ogg
  7. BIN
      asset/sound/the_world_is_a_landfill_and_its_your_fault_you_fucking_son_of_a_bitch_god_damn.ogg
  8. BIN
      asset/sound/we_will_build_it.ogg
  9. 6
      go.mod
  10. 12
      go.sum
  11. 44
      system/input_move.go
  12. 4
      system/populate.go
  13. 33
      system/renderhud.go
  14. 4
      system/tax.go
  15. 7
      system/tick.go
  16. 8
      world/help.go
  17. 115
      world/world.go

13
CHANGELOG

@ -0,0 +1,13 @@
v1.1.0
- Fixed bulldozer
- Fixed tax system (now collected per citizen)
- Fixed building unintentionally when adjusting tax rates
- Fixed game crash on Windows
- Added city population indicator
- Added center camera via right click
- Added new music to soundtrack
- Removed screen edge scrolling
- Removed middle mouse scrolling
v1.0.0
- Initial release

35
asset/asset.go

@ -28,14 +28,21 @@ var (
)
var (
SoundMusic *audio.Player
SoundMusic1 *audio.Player
SoundMusic2 *audio.Player
SoundMusic3 *audio.Player
SoundSelect *audio.Player
SoundBulldoze *audio.Player
SoundPop1 *audio.Player
SoundPop2 *audio.Player
SoundPop3 *audio.Player
SoundPop4 *audio.Player
SoundPop5 *audio.Player
SoundPop1 *audio.Player
SoundPop2 *audio.Player
SoundPop3 *audio.Player
SoundPop4 *audio.Player
SoundPop5 *audio.Player
SoundExplosion1 *audio.Player
SoundExplosion2 *audio.Player
)
func init() {
@ -44,8 +51,14 @@ func init() {
}
func LoadSounds(ctx *audio.Context) {
SoundMusic = LoadOGG(ctx, "sound/we_will_build_it.ogg", true)
SoundMusic.SetVolume(0.6)
SoundMusic1 = LoadOGG(ctx, "sound/we_will_build_it.ogg", false)
SoundMusic1.SetVolume(0.6)
SoundMusic2 = LoadOGG(ctx, "sound/please_recycle.ogg", false)
SoundMusic2.SetVolume(0.1)
SoundMusic3 = LoadOGG(ctx, "sound/the_world_is_a_landfill_and_its_your_fault_you_fucking_son_of_a_bitch_god_damn.ogg", false)
SoundMusic3.SetVolume(0.4)
SoundSelect = LoadWAV(ctx, "sound/select/select.wav")
SoundSelect.SetVolume(0.6)
@ -64,6 +77,12 @@ func LoadSounds(ctx *audio.Context) {
SoundPop3.SetVolume(popVolume)
SoundPop4.SetVolume(popVolume)
SoundPop5.SetVolume(popVolume)
const explosionVolume = 0.1
SoundExplosion1 = LoadOGG(ctx, "sound/explosion/explosion1.ogg", false)
SoundExplosion2 = LoadOGG(ctx, "sound/explosion/explosion2.ogg", false)
SoundExplosion1.SetVolume(explosionVolume)
SoundExplosion2.SetVolume(explosionVolume)
}
func LoadImage(p string) *ebiten.Image {

8
asset/sound/explosion/LICENSE

@ -0,0 +1,8 @@
These sound clips were made available for use by derplayer under the
Creative Commons 0 License.
Sources:
- https://freesound.org/people/derplayer/sounds/587194/
- https://freesound.org/people/derplayer/sounds/587193/
License: http://creativecommons.org/publicdomain/zero/1.0/

BIN
asset/sound/explosion/explosion1.ogg

Binary file not shown.

BIN
asset/sound/explosion/explosion2.ogg

Binary file not shown.

BIN
asset/sound/please_recycle.ogg

Binary file not shown.

BIN
asset/sound/the_world_is_a_landfill_and_its_your_fault_you_fucking_son_of_a_bitch_god_damn.ogg

Binary file not shown.

BIN
asset/sound/we_will_build_it.ogg

Binary file not shown.

6
go.mod

@ -17,8 +17,10 @@ require (
github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240 // indirect
github.com/jfreymuth/oggvorbis v1.0.3 // indirect
github.com/jfreymuth/vorbis v1.0.2 // indirect
golang.org/x/exp v0.0.0-20220121174013-7b334a16533f // indirect
golang.org/x/exp v0.0.0-20220128181451-c853b6ddb95e // indirect
golang.org/x/mobile v0.0.0-20220112015953-858099ff7816 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect
)
replace github.com/lafriks/go-tiled => github.com/tslocum/go-tiled v0.7.1-0.20220129040705-2d2dec486bd9

12
go.sum

@ -25,14 +25,14 @@ github.com/jfreymuth/oggvorbis v1.0.3 h1:MLNGGyhOMiVcvea9Dp5+gbs2SAwqwQbtrWnonYa
github.com/jfreymuth/oggvorbis v1.0.3/go.mod h1:1U4pqWmghcoVsCJJ4fRBKv9peUJMBHixthRlBeD6uII=
github.com/jfreymuth/vorbis v1.0.2 h1:m1xH6+ZI4thH927pgKD8JOH4eaGRm18rEE9/0WKjvNE=
github.com/jfreymuth/vorbis v1.0.2/go.mod h1:DoftRo4AznKnShRl1GxiTFCseHr4zR9BN3TWXyuzrqQ=
github.com/lafriks/go-tiled v0.7.0 h1:xb1iVYtPpjpHx9i/LjqHwoS2xdfrihCsFRKOFn7fOBU=
github.com/lafriks/go-tiled v0.7.0/go.mod h1:xy+4iO8AKWpFNBWeqBqnq+Cb3Oirm5oin/irP/jPx6A=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tslocum/go-tiled v0.7.1-0.20220129040705-2d2dec486bd9 h1:Uf42chMg2Cp5/qZkb9QIPzXgn9jM6Mv2Wp5tOIpVDcY=
github.com/tslocum/go-tiled v0.7.1-0.20220129040705-2d2dec486bd9/go.mod h1:xy+4iO8AKWpFNBWeqBqnq+Cb3Oirm5oin/irP/jPx6A=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -40,8 +40,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20220121174013-7b334a16533f h1:u4dL7EmDaaJ+1e0HD9rawKa15yKPQZWXQ/epCOPAU+A=
golang.org/x/exp v0.0.0-20220121174013-7b334a16533f/go.mod h1:M50CtfS+xv2iy/epuEazynj250ScQ0/DOjcsin9UE8k=
golang.org/x/exp v0.0.0-20220128181451-c853b6ddb95e h1:FmsvSkPHPBTboKvYBUtHbHvkQGxq+XSrqPXKDQf2W3s=
golang.org/x/exp v0.0.0-20220128181451-c853b6ddb95e/go.mod h1:M50CtfS+xv2iy/epuEazynj250ScQ0/DOjcsin9UE8k=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@ -74,8 +74,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

44
system/input_move.go

@ -57,7 +57,7 @@ func (s *playerMoveSystem) buildStructure(structureType int, tileX int, tileY in
return nil, errors.New("insufficient funds")
}
structure, err := world.BuildStructure(world.World.HoverStructure, false, tileX, tileY)
structure, err := world.BuildStructure(world.World.HoverStructure, false, tileX, tileY, false)
if err == nil || world.World.HoverStructure == world.StructureBulldozer {
world.World.LastBuildX, world.World.LastBuildY = tileX, tileY
@ -147,12 +147,19 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
if inpututil.IsKeyJustPressed(ebiten.KeyM) {
world.World.MuteMusic = !world.World.MuteMusic
if world.World.MuteMusic {
asset.SoundMusic.Pause()
asset.SoundMusic1.Pause()
asset.SoundMusic2.Pause()
asset.SoundMusic3.Pause()
} else {
asset.SoundMusic.Play()
world.ResumeSong()
}
}
if inpututil.IsKeyJustPressed(ebiten.KeyN) {
world.World.MuteMusic = false
world.PlayNextSong()
}
if world.World.GameOver {
if inpututil.IsKeyJustPressed(ebiten.KeyEnter) {
world.World.ResetGame = true
@ -213,7 +220,6 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
}
}
const scrollEdgeSize = 1
x, y := ebiten.CursorPosition()
if !world.World.GotCursorPosition {
if x != 0 || y != 0 {
@ -237,18 +243,12 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
if s.scrollDragX != -1 && s.scrollDragY != -1 {
s.scrollDragX, s.scrollDragY = -1, -1
//ebiten.SetCursorMode(ebiten.CursorModeVisible)
} else if x >= -2 && y >= -2 && x < world.World.ScreenW+2 && y < world.World.ScreenH+2 {
// Pan via screen edge.
if x <= scrollEdgeSize {
world.World.CamX -= camSpeed
} else if x >= world.World.ScreenW-scrollEdgeSize-1 {
world.World.CamX += camSpeed
}
if y <= scrollEdgeSize {
world.World.CamY -= camSpeed
} else if y >= world.World.ScreenH-scrollEdgeSize-1 {
world.World.CamY += camSpeed
}
}
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonRight) {
vX, vY := world.World.ScreenW/2-x, world.World.ScreenH/2-y
dx, dy := float64(vX)/world.World.CamScale, float64(vY)/world.World.CamScale
world.World.CamX, world.World.CamY = world.World.CamX-dx, world.World.CamY-dy
}
}
// Clamp viewport.
@ -309,7 +309,9 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
return nil
}
world.HandleRCIWindowClick(x, y)
if world.HandleRCIWindow(x, y) {
return nil
}
if x >= world.World.ScreenW-helpW && y >= world.World.ScreenH-helpH {
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
@ -408,10 +410,10 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
// TODO draw hover sprites
// TODO move below into shared func
world.World.Level.ClearHoverSprites()
world.BuildStructure(world.World.HoverStructure, true, int(tileX), int(tileY))
world.BuildStructure(world.World.HoverStructure, true, int(tileX), int(tileY), false)
var cost int
for _, tile := range tiles {
world.BuildStructure(world.World.HoverStructure, true, tile[0], tile[1])
world.BuildStructure(world.World.HoverStructure, true, tile[0], tile[1], false)
cost += world.StructureCosts[world.World.HoverStructure]
}
world.World.HoverValid = cost <= world.World.Funds
@ -441,13 +443,13 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
}
if world.World.HoverStructure > 0 {
world.BuildStructure(world.World.HoverStructure, true, int(tileX), int(tileY))
world.BuildStructure(world.World.HoverStructure, true, int(tileX), int(tileY), false)
}
}
} else {
world.World.Level.ClearHoverSprites()
world.BuildStructure(world.World.HoverStructure, true, int(tileX), int(tileY))
world.BuildStructure(world.World.HoverStructure, true, int(tileX), int(tileY), false)
}
world.World.HoverX, world.World.HoverY = int(tileX), int(tileY)
}

4
system/populate.go

@ -130,10 +130,10 @@ func (s *PopulateSystem) Update(_ *gohan.Context) error {
// TODO only bulldoze when changed
for offsetX := 0; offsetX < 2; offsetX++ {
for offsetY := 0; offsetY < 2; offsetY++ {
world.BuildStructure(world.StructureBulldozer, false, zone.X-offsetX, zone.Y-offsetY)
world.BuildStructure(world.StructureBulldozer, false, zone.X-offsetX, zone.Y-offsetY, true)
}
}
world.BuildStructure(newType, false, zone.X, zone.Y)
world.BuildStructure(newType, false, zone.X, zone.Y, true)
}
// TODO populate and de-populate zones by target population

33
system/renderhud.go

@ -149,6 +149,8 @@ func (s *RenderHudSystem) drawSidebar() {
// Draw PWR indicator.
s.drawPower(buttonWidth/2+buttonWidth, indicatorY)
s.drawPopulation(world.World.ScreenH - 45)
s.hudImg.DrawImage(s.tmpImg, nil)
s.hudImg.SubImage(image.Rect(world.SidebarWidth-1, 0, world.SidebarWidth, world.World.ScreenH)).(*ebiten.Image).Fill(color.Black)
@ -418,6 +420,37 @@ func (s *RenderHudSystem) drawFunds(y int) {
s.hudImg.DrawImage(s.tmpImg2, op)
}
func (s *RenderHudSystem) drawPopulation(y int) {
var population int
for _, zone := range world.World.Zones {
population += zone.Population
}
const datePadding = 10
label := "Pop"
scale := 2.0
x, y := datePadding, y
s.tmpImg2.Clear()
ebitenutil.DebugPrint(s.tmpImg2, label)
op := &ebiten.DrawImageOptions{}
op.GeoM.Scale(scale, scale)
op.GeoM.Translate(float64(x), float64(y))
s.hudImg.DrawImage(s.tmpImg2, op)
label = world.World.Printer.Sprintf("%d", population)
x = world.SidebarWidth - 1 - datePadding - (len(label) * 6 * int(scale))
s.tmpImg2.Clear()
ebitenutil.DebugPrint(s.tmpImg2, label)
op.GeoM.Reset()
op.GeoM.Scale(scale, scale)
op.GeoM.Translate(float64(x), float64(y))
s.hudImg.DrawImage(s.tmpImg2, op)
}
func (s *RenderHudSystem) drawHelp() {
if world.World.HelpPage < 0 {
return

4
system/tax.go

@ -37,7 +37,7 @@ func (s *TaxSystem) Update(_ *gohan.Context) error {
return nil
}
taxCollectionAmount := 777.77
taxCollectionAmount := 27.77
for _, zone := range world.World.Zones {
if zone.Population == 0 {
continue
@ -50,7 +50,7 @@ func (s *TaxSystem) Update(_ *gohan.Context) error {
taxRate = world.World.TaxI
}
world.World.Funds += int(taxCollectionAmount * taxRate)
world.World.Funds += int(taxCollectionAmount * taxRate * float64(zone.Population))
}
return nil
}

7
system/tick.go

@ -1,6 +1,7 @@
package system
import (
"code.rocketnine.space/tslocum/citylimits/asset"
"code.rocketnine.space/tslocum/citylimits/component"
"code.rocketnine.space/tslocum/citylimits/world"
"code.rocketnine.space/tslocum/gohan"
@ -33,14 +34,18 @@ func (s *TickSystem) Update(_ *gohan.Context) error {
return nil
}
world.World.Ticks++
// Update date display.
if world.World.Ticks%world.MonthTicks == 0 {
world.World.HUDUpdated = true
}
if world.World.Ticks%144 == 0 {
world.TickMessages()
if !world.World.MuteMusic && !asset.SoundMusic1.IsPlaying() && !asset.SoundMusic2.IsPlaying() && !asset.SoundMusic3.IsPlaying() {
world.PlayNextSong()
}
}
world.World.Ticks++
return nil
}

8
world/help.go

@ -9,10 +9,10 @@ Will you lead the clean energy front,
or will you put profits before people?
`, `
Moving Via Mouse (2/10)
To move around, place your cursor at
the edge of the screen, or press and
hold your middle mouse button while
moving your cursor.
To move around, press and hold your
middle mouse button while moving your
mouse, or press right click to center
the camera on an area immediately.
`, `
Moving Via Keyboard (3/10)
You can also use your keyboard to move

115
world/world.go

@ -211,6 +211,8 @@ type GameWorld struct {
TaxC float64
TaxI float64
playingSong int
resetTipShown bool
}
@ -237,6 +239,7 @@ func Reset() {
World.CamX = float64((32 * TileSize) - rand.Intn(64*TileSize))
World.CamY = float64((32 * TileSize) + rand.Intn(32*TileSize))
World.playingSong = rand.Intn(3)
}
func LoadMap(structureType int) (*tiled.Map, error) {
@ -246,7 +249,7 @@ func LoadMap(structureType int) (*tiled.Map, error) {
}
// Parse .tmx file.
m, err := tiled.LoadFile(filepath.FromSlash(filePath), tiled.WithFileSystem(asset.FS))
m, err := tiled.LoadFile(filePath, tiled.WithFileSystem(asset.FS))
if err != nil {
log.Fatalf("error parsing world: %+v", err)
}
@ -309,7 +312,7 @@ func LoadTileset() error {
tileset := m.Tilesets[0]
imgPath := filepath.Join("./image/tileset/", tileset.Image.Source)
f, err := asset.FS.Open(filepath.FromSlash(imgPath))
f, err := asset.FS.Open(filepath.ToSlash(imgPath))
if err != nil {
panic(err)
}
@ -346,7 +349,15 @@ func ShowBuildCost(structureType int, cost int) {
}
}
func BuildStructure(structureType int, hover bool, placeX int, placeY int) (*Structure, error) {
func bulldozeArea(x int, y int, size int) {
for dx := 0; dx < size; dx++ {
for dy := 0; dy < size; dy++ {
BuildStructure(StructureBulldozer, false, x-dx, y-dy, true)
}
}
}
func BuildStructure(structureType int, hover bool, placeX int, placeY int, internal bool) (*Structure, error) {
m, err := LoadMap(structureType)
if err != nil {
return nil, err
@ -407,6 +418,47 @@ func BuildStructure(structureType int, hover bool, placeX int, placeY int) (*Str
if !bulldozed {
return nil, ErrNothingToBulldoze
}
if !internal {
var bulldozeStructure bool
checkSpaces := 2
REMOVEZONES:
for i, zone := range World.Zones {
for dx := 0; dx < checkSpaces; dx++ {
for dy := 0; dy < checkSpaces; dy++ {
if placeX == zone.X-dx && placeY == zone.Y-dy {
World.Zones = append(World.Zones[:i], World.Zones[i+1:]...)
bulldozeArea(zone.X, zone.Y, 2)
bulldozeStructure = true
break REMOVEZONES
}
}
}
}
checkSpaces = 5
REMOVEPOWER:
for i, plant := range World.PowerPlants {
for dx := 0; dx < checkSpaces; dx++ {
for dy := 0; dy < checkSpaces; dy++ {
if placeX == plant.X-dx && placeY == plant.Y-dy {
World.PowerPlants = append(World.PowerPlants[:i], World.PowerPlants[i+1:]...)
bulldozeArea(plant.X, plant.Y, 5)
bulldozeStructure = true
World.PowerUpdated = true
break REMOVEPOWER
}
}
}
}
if bulldozeStructure {
sounds := []*audio.Player{
asset.SoundExplosion1,
asset.SoundExplosion2,
}
sound := sounds[rand.Intn(len(sounds))]
sound.Rewind()
sound.Play()
}
}
World.Power.SetTile(placeX, placeY, false)
return structure, nil
}
@ -558,10 +610,6 @@ func StartGame() {
}
World.GameStarted = true
if !World.MuteMusic {
asset.SoundMusic.Play()
}
// Show initial help page.
SetHelpPage(0)
}
@ -627,18 +675,18 @@ func AltButtonAt(x, y int) int {
return -1
}
func HandleRCIWindowClick(x, y int) {
func HandleRCIWindow(x, y int) bool {
if !World.ShowRCIWindow {
return
}
if !ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
return
return false
}
point := image.Point{x, y}
if !point.In(World.RCIWindowRect) {
return
return false
}
if !ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
return true
}
var updated bool
@ -668,7 +716,7 @@ func HandleRCIWindowClick(x, y int) {
updated = true
}
if !updated {
return
return true
}
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) || World.Ticks%16 == 0 {
@ -683,6 +731,7 @@ func HandleRCIWindowClick(x, y int) {
sound.Rewind()
sound.Play()
}
return true
}
func SetHoverStructure(structureType int) {
@ -866,3 +915,39 @@ func IsPowerPlant(structureType int) bool {
func IsZone(structureType int) bool {
return structureType == StructureResidentialZone || structureType == StructureCommercialZone || structureType == StructureIndustrialZone
}
func PlayNextSong() {
const numSongs = 3
asset.SoundMusic1.Pause()
asset.SoundMusic2.Pause()
asset.SoundMusic3.Pause()
World.playingSong++
if World.playingSong == numSongs {
World.playingSong = 0
}
switch World.playingSong {
case 0:
asset.SoundMusic1.Rewind()
asset.SoundMusic1.Play()
case 1:
asset.SoundMusic2.Rewind()
asset.SoundMusic2.Play()
case 2:
asset.SoundMusic3.Rewind()
asset.SoundMusic3.Play()
}
}
func ResumeSong() {
switch World.playingSong {
case 0:
asset.SoundMusic1.Play()
case 1:
asset.SoundMusic2.Play()
case 2:
asset.SoundMusic3.Play()
}
}

Loading…
Cancel
Save