Skip to content

Commit

Permalink
Merge branch 'master' into water-units
Browse files Browse the repository at this point in the history
  • Loading branch information
kazzmir committed Feb 6, 2025
2 parents 737ae12 + 50c1be0 commit 9003873
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 26 deletions.
29 changes: 24 additions & 5 deletions game/magic/city/city.go
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,7 @@ func (city *City) ComputeUnrest(garrison []units.StackUnit) int {

unrestPercent += city.InteracialUnrest()

// unrest from curses
if city.HasEnchantment(data.CityEnchantmentFamine) {
unrestPercent += 0.25
}
Expand Down Expand Up @@ -878,6 +879,11 @@ func (city *City) ComputeUnrest(garrison []units.StackUnit) int {
pacification += float64(oraclePacification(city.Race))
}

// pacification from enchantments
if city.HasEnchantment(data.CityEnchantmentGaiasBlessing) {
pacification += 2
}

total := unrestPercent * float64(city.Citizens()) + unrestAbsolute - pacification - garrisonSupression / 2

return int(math.Max(0, total))
Expand All @@ -890,6 +896,10 @@ func (city *City) MaximumCitySize() int {

// TODO: 1/2 if famine is active

if city.HasEnchantment(data.CityEnchantmentGaiasBlessing) {
foodAvailability += int(0.5 * float32(foodAvailability))
}

bonus := 0

if city.Buildings.Contains(buildinglib.BuildingGranary) {
Expand Down Expand Up @@ -930,6 +940,10 @@ func (city *City) PopulationGrowthRate() int {
base += 30
}

if city.HasEnchantment(data.CityEnchantmentGaiasBlessing) {
base += int(2.5 * float32(city.MaximumCitySize()) / 10) * 10
}

if city.SurplusFood() < 0 {
base = 50 * city.SurplusFood()
}
Expand Down Expand Up @@ -987,13 +1001,17 @@ func (city *City) FoodProductionRate() int {
}

func (city *City) FarmerFoodProduction(farmers int) int {
rate := 2
food := 2 * farmers

switch city.Race {
case data.RaceHalfling: rate = 3
if city.Race == data.RaceHalfling {
food += farmers
}

if city.HasEnchantment(data.CityEnchantmentGaiasBlessing) {
food += int(float32(food) * 0.2)
}

return rate * farmers
return food
}

func (city *City) foodProductionRate(farmers int) int {
Expand Down Expand Up @@ -1233,9 +1251,10 @@ func (city *City) ProductionTerrain() float32 {
catchment := city.CatchmentProvider.GetCatchmentArea(city.X, city.Y)
production := float32(0)
mineralProduction := float32(0)
hasGaiasBlessing := city.HasEnchantment(data.CityEnchantmentGaiasBlessing)

for _, tile := range catchment {
production += float32(tile.ProductionBonus()) / 100
production += float32(tile.ProductionBonus(hasGaiasBlessing)) / 100

// FIXME: This should be only when producing units
mineralProduction += float32(tile.GetBonus().UnitReductionBonus()) / 100
Expand Down
3 changes: 1 addition & 2 deletions game/magic/data/enchantment.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,7 @@ func (enchantment CityEnchantment) SoundIndex() int {
case CityEnchantmentDarkRituals: return 60
// case CityEnchantmentEarthGate: return 0
// case CityEnchantmentFlyingFortress: return 0
// case CityEnchantmentGaiasBlessing: return 0
case CityEnchantmentNaturesEye: return 28
case CityEnchantmentGaiasBlessing, CityEnchantmentNaturesEye: return 28
// case CityEnchantmentPestilence: return 0
// case CityEnchantmentLifeWard: return 0
// case CityEnchantmentSorceryWard: return 0
Expand Down
6 changes: 6 additions & 0 deletions game/magic/game/cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ func (game *Game) doCastSpell(player *playerlib.Player, spell spellbook.Spell) {
game.doCastCityEnchantment(yield, tileX, tileY, player, data.CityEnchantmentInspirations)
}

game.Events <- &GameEventSelectLocationForSpell{Spell: spell, Player: player, LocationType: LocationTypeFriendlyCity, SelectedFunc: selected}
case "Gaia's Blessing":
selected := func (yield coroutine.YieldFunc, tileX int, tileY int){
game.doCastCityEnchantment(yield, tileX, tileY, player, data.CityEnchantmentGaiasBlessing)
}

game.Events <- &GameEventSelectLocationForSpell{Spell: spell, Player: player, LocationType: LocationTypeFriendlyCity, SelectedFunc: selected}
case "Cursed Lands":
selected := func (yield coroutine.YieldFunc, tileX int, tileY int){
Expand Down
44 changes: 43 additions & 1 deletion game/magic/game/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -4726,7 +4726,7 @@ func (game *Game) CityProductionBonus(x int, y int, plane data.Plane) int {
production := 0

for _, tile := range catchment {
production += tile.ProductionBonus()
production += tile.ProductionBonus(false)
}

return production
Expand Down Expand Up @@ -5976,6 +5976,46 @@ func (game *Game) DissipateEnchantments(player *playerlib.Player, power int) {
// FIXME: dissipate unit enchantments
}

// apply automatic terraforming and purification to all cities of a player with gaias blessing
func (game *Game) doGaiasBlessing(player *playerlib.Player) {
for _, city := range player.Cities {
if city.HasEnchantment(data.CityEnchantmentGaiasBlessing) {

mapObject := game.GetMap(city.Plane)

for dx := -2; dx <= 2; dx++ {
for dy := -2; dy <= 2; dy++ {
mx := player.WrapX(city.X + dx)
my := city.Y + dy

if mx < 0 || mx >= mapObject.Width() || my < 0 || my >= mapObject.Height() {
continue
}

tile := mapObject.GetTile(mx, my)
terrainType := tile.Tile.TerrainType()

// 10% chance to convert volcanos to hills
if mapObject.HasVolcano(mx, my) && rand.IntN(100) < 10 {
mapObject.RemoveVolcano(mx, my)
mapObject.Map.SetTerrainAt(mx, my, terrain.Hill, mapObject.Data, mapObject.Plane)
}

// 10% chance to convert desert to grassland
if terrainType == terrain.Desert && rand.IntN(100) < 10 {
mapObject.Map.SetTerrainAt(mx, mx, terrain.Grass, mapObject.Data, mapObject.Plane)
}

// 20% chance to remove corruption
if mapObject.HasCorruption(mx, my) && rand.IntN(100) < 20 {
mapObject.RemoveCorruption(mx, my)
}
}
}
}
}
}

func (game *Game) StartPlayerTurn(player *playerlib.Player) {
disbandedMessages := game.DisbandUnits(player)

Expand Down Expand Up @@ -6185,6 +6225,8 @@ func (game *Game) StartPlayerTurn(player *playerlib.Player) {
player.RemoveCity(city)
}

game.doGaiasBlessing(player)

game.maybeHireHero(player)
game.maybeHireMercenaries(player)
game.maybeBuyFromMerchant(player)
Expand Down
2 changes: 1 addition & 1 deletion game/magic/game/surveyor.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func (game *Game) doSurveyor(yield coroutine.YieldFunc) {
y += float64(whiteFont.Height() * data.ScreenScale)
}

productionBonus := tile.ProductionBonus()
productionBonus := tile.ProductionBonus(false)
if productionBonus != 0 {
whiteFont.PrintCenter(screen, float64(280 * data.ScreenScale), y, float64(data.ScreenScale), ebiten.ColorScale{}, fmt.Sprintf("+%v%% production", productionBonus))
y += float64(whiteFont.Height() * data.ScreenScale)
Expand Down
32 changes: 15 additions & 17 deletions game/magic/maplib/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,27 +617,20 @@ func (tile *FullTile) GoldBonus(mapObject *Map) int {
}

// percent bonus increase, 3 = 3%
func (tile *FullTile) ProductionBonus() int {
func (tile *FullTile) ProductionBonus(hasGaiasBlessing bool) int {
if tile.Corrupted() {
return 0
}

switch tile.Tile.TerrainType() {
case terrain.Ocean: return 0
case terrain.Grass: return 0
case terrain.Forest: return 3
case terrain.Mountain: return 5
case terrain.Desert: return 3
case terrain.Swamp: return 0
case terrain.Tundra: return 0
case terrain.SorceryNode: return 0
case terrain.NatureNode: return 3
case terrain.ChaosNode: return 5
case terrain.Hill: return 3
case terrain.Volcano: return 0
case terrain.Lake: return 0
case terrain.River: return 0
case terrain.Shore: return 0
terrainType := tile.Tile.TerrainType()
switch {
case terrainType == terrain.Forest && hasGaiasBlessing: return 6
case terrainType == terrain.Forest: return 3
case terrainType == terrain.Mountain: return 5
case terrainType == terrain.Desert: return 3
case terrainType == terrain.NatureNode: return 3
case terrainType == terrain.ChaosNode: return 5
case terrainType == terrain.Hill: return 3
}

return 0
Expand Down Expand Up @@ -1062,6 +1055,11 @@ func (mapObject *Map) SetVolcano(x int, y int, caster Wizard) {
mapObject.Map.SetTerrainAt(x, y, terrain.Volcano, mapObject.Data, mapObject.Plane)
}

func (mapObject *Map) HasVolcano(x int, y int) bool {
_, exists := mapObject.ExtraMap[image.Pt(x, y)][ExtraKindVolcano]
return exists
}

func (mapObject *Map) RemoveVolcano(x int, y int) {
_, exists := mapObject.ExtraMap[image.Pt(x, y)][ExtraKindVolcano]
if exists {
Expand Down
1 change: 1 addition & 0 deletions test/overworld/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,7 @@ func createScenario13(cache *lbx.LbxCache) *gamelib.Game {
player.KnownSpells.AddSpell(allSpells.FindByName("Nature's Eye"))
player.KnownSpells.AddSpell(allSpells.FindByName("Prosperity"))
player.KnownSpells.AddSpell(allSpells.FindByName("Inspirations"))
player.KnownSpells.AddSpell(allSpells.FindByName("Gaia's Blessing"))
player.KnownSpells.AddSpell(allSpells.FindByName("Cursed Lands"))
player.KnownSpells.AddSpell(allSpells.FindByName("Famine"))
player.KnownSpells.AddSpell(allSpells.FindByName("Nature Awareness"))
Expand Down

0 comments on commit 9003873

Please sign in to comment.