diff --git a/game/magic/cityview/city-screen.go b/game/magic/cityview/city-screen.go index 40ed8e74..2fafba19 100644 --- a/game/magic/cityview/city-screen.go +++ b/game/magic/cityview/city-screen.go @@ -566,43 +566,111 @@ func (cityScreen *CityScreen) MakeUI(newBuilding buildinglib.Building) *uilib.UI elements = append(elements, makeCityScapeElement(cityScreen.LbxCache, ui, cityScreen.City, &help, &cityScreen.ImageCache, sellBuilding, cityScreen.Buildings, newBuilding, 4 * data.ScreenScale, 102 * data.ScreenScale, cityScreen.Fonts, cityScreen.Player, &getAlpha)) - // FIXME: show disabled buy button if the item is not buyable (not enough money, or the item is trade goods/housing) - // buy button - buyButton, err := cityScreen.ImageCache.GetImage("backgrnd.lbx", 7, 0) - if err == nil { - buyX := 214 * data.ScreenScale - buyY := 188 * data.ScreenScale - elements = append(elements, &uilib.UIElement{ - Rect: image.Rect(buyX, buyY, buyX + buyButton.Bounds().Dx(), buyY + buyButton.Bounds().Dy()), - PlaySoundLeftClick: true, - LeftClick: func(element *uilib.UIElement) { + // returns the amount of gold and the amount of production that will be used to buy a building + computeBuyAmount := func(cost int) (int, float32) { + // FIXME: take terrain/race/buildings into effect, such as the miners guild for dwarves + + remaining := float32(cost) - cityScreen.City.Production + if remaining > 0 { + modifier := float32(4) + if cityScreen.City.Production == 0 { + modifier = 4 + } else if cityScreen.City.Production / float32(cost) < 1.0/3 { + modifier = 3 + } else { + modifier = 2 + } - var elements []*uilib.UIElement + buyAmount := int(remaining * modifier) + buyProduction := remaining - yes := func(){ - // FIXME: buy the thing being produced - } + return buyAmount, buyProduction + } - no := func(){ - } + return 0, 0 + } - elements = uilib.MakeConfirmDialog(cityScreen.UI, cityScreen.LbxCache, &cityScreen.ImageCache, "Are you sure you want to buy this building?", true, yes, no) - ui.AddElements(elements) - }, - RightClick: func(element *uilib.UIElement) { - helpEntries := help.GetEntries(305) - if helpEntries != nil { - ui.AddElement(uilib.MakeHelpElement(ui, cityScreen.LbxCache, &cityScreen.ImageCache, helpEntries[0])) - } - }, - Draw: func(element *uilib.UIElement, screen *ebiten.Image) { - var options ebiten.DrawImageOptions - options.GeoM.Translate(float64(element.Rect.Min.X), float64(element.Rect.Min.Y)) - screen.DrawImage(buyButton, &options) - }, - }) + buyAmount := 0 + buyProduction := float32(0) + + if cityScreen.City.ProducingBuilding != buildinglib.BuildingNone && cityScreen.City.ProducingBuilding != buildinglib.BuildingTradeGoods && cityScreen.City.ProducingBuilding != buildinglib.BuildingHousing { + cost := float32(cityScreen.City.BuildingInfo.ProductionCost(cityScreen.City.ProducingBuilding)) + buyAmount, buyProduction = computeBuyAmount(int(cost)) } + if !cityScreen.City.ProducingUnit.IsNone() { + buyAmount, buyProduction = computeBuyAmount(cityScreen.City.ProducingUnit.ProductionCost) + } + + // true if there is something to buy + canBuy := buyProduction > 0 && buyAmount <= cityScreen.Player.Gold + + buyButtons, _ := cityScreen.ImageCache.GetImages("backgrnd.lbx", 7) + if !canBuy { + buyButtons, _ = cityScreen.ImageCache.GetImages("backgrnd.lbx", 14) + } + + buyIndex := 0 + buyX := 214 * data.ScreenScale + buyY := 188 * data.ScreenScale + elements = append(elements, &uilib.UIElement{ + Rect: image.Rect(buyX, buyY, buyX + buyButtons[0].Bounds().Dx(), buyY + buyButtons[0].Bounds().Dy()), + PlaySoundLeftClick: true, + LeftClick: func(element *uilib.UIElement) { + if !canBuy { + return + } + + buyIndex = 1 + }, + LeftClickRelease: func(element *uilib.UIElement) { + if !canBuy { + return + } + + buyIndex = 0 + + var elements []*uilib.UIElement + + yes := func(){ + cityScreen.City.Production += buyProduction + cityScreen.Player.Gold -= buyAmount + cityScreen.UI = cityScreen.MakeUI(buildinglib.BuildingNone) + } + + no := func(){ + } + + var name string + if cityScreen.City.ProducingBuilding != buildinglib.BuildingNone { + name = cityScreen.City.BuildingInfo.Name(cityScreen.City.ProducingBuilding) + } else { + name = cityScreen.City.ProducingUnit.Name + } + message := fmt.Sprintf("Do you wish to spend %v by purchasing a %v?", buyAmount, name) + elements = uilib.MakeConfirmDialog(cityScreen.UI, cityScreen.LbxCache, &cityScreen.ImageCache, message, false, yes, no) + ui.AddElements(elements) + + }, + RightClick: func(element *uilib.UIElement) { + helpEntries := help.GetEntries(305) + if helpEntries != nil { + ui.AddElement(uilib.MakeHelpElement(ui, cityScreen.LbxCache, &cityScreen.ImageCache, helpEntries[0])) + } + }, + Draw: func(element *uilib.UIElement, screen *ebiten.Image) { + var options ebiten.DrawImageOptions + options.GeoM.Translate(float64(element.Rect.Min.X), float64(element.Rect.Min.Y)) + + use := 0 + if buyIndex < len(buyButtons) { + use = buyIndex + } + + screen.DrawImage(buyButtons[use], &options) + }, + }) + // change button changeButton, err := cityScreen.ImageCache.GetImage("backgrnd.lbx", 8, 0) if err == nil { diff --git a/game/magic/ui/dialogs.go b/game/magic/ui/dialogs.go index 50ea6550..a14377c4 100644 --- a/game/magic/ui/dialogs.go +++ b/game/magic/ui/dialogs.go @@ -264,7 +264,7 @@ func MakeConfirmDialogWithLayer(ui *UI, cache *lbx.LbxCache, imageCache *util.Im func MakeConfirmDialogWithLayerFull(ui *UI, cache *lbx.LbxCache, imageCache *util.ImageCache, layer UILayer, message string, center bool, confirm func(), cancel func(), yesButtons []*ebiten.Image, noButtons []*ebiten.Image) []*UIElement { confirmX := 67 * data.ScreenScale - confirmY := 73 * data.ScreenScale + confirmY := 68 * data.ScreenScale confirmMargin := 15 * data.ScreenScale confirmTopMargin := 10 * data.ScreenScale diff --git a/test/cityview/main.go b/test/cityview/main.go index 58d13040..5fad38ba 100644 --- a/test/cityview/main.go +++ b/test/cityview/main.go @@ -52,6 +52,8 @@ func NewEngine() (*Engine, error) { }, } + player.Gold = 500 + buildingInfo, _ := buildinglib.ReadBuildingInfo(cache) terrainLbx, err := cache.GetLbxFile("terrain.lbx") diff --git a/test/overworld/main.go b/test/overworld/main.go index 3257deb6..aa7313eb 100644 --- a/test/overworld/main.go +++ b/test/overworld/main.go @@ -251,7 +251,7 @@ func createScenario3(cache *lbx.LbxCache) *gamelib.Game { player.AddCity(introCity) - player.Gold = 83 + player.Gold = 5000 player.Mana = 26 // game.Map.Map.Terrain[3][6] = terrain.TileNatureForest.Index