Natural Wonders (#1456)

* NaturalWonders initial commit
* Created models/ruleset/tile/NaturalWonder and assets/json/NaturalWonders
* MapGenerator now spawns NaturalWonders in random compatible random locations
* MapParameters has a noNaturalWonders option
* TileInfo has naturalWonder property (set to null if none)
* TileInfo and  UnitMovementAlgorithms correctly manages stats and consider the tile unpassable and unimprovable

* Notification and happiness on NaturalWonder discovery

* El Dorado discovery bonus, Spain unique

* Doubled tile yields for Spain

* NaturalWonders implemented as TerrainType + Fountain of Youth promotion

* Images issue #124

* NaturalWonder TileImages (Fantasy) and Overlay (Default)

* NaturalWonderOverlay.png : https://www.flaticon.com/free-icon/mount-fuji_2166259

* Bugfix

* Added translations

* Italian translations

* Fix translation issue
* missing space after = in template.properties breaks translations

* Improved NaturalWonder spawn logic

* Great Barrier Reef spawns on 2 contiguous tiles
* Each wonder has specific spawn requirements
* Number of wonders spawned scales with map radius

* Fix unused import
This commit is contained in:
r3versi 2019-12-16 19:37:49 +01:00 committed by Yair Morgenstern
parent 0366233be5
commit aa02a2d321
51 changed files with 3008 additions and 1951 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 876 KiB

After

Width:  |  Height:  |  Size: 877 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 KiB

After

Width:  |  Height:  |  Size: 285 KiB

View File

@ -769,7 +769,7 @@
"Almarikh","Ulaanbaatar","Hovd","Darhan","Dalandzadgad","Mandalgovi","Choybalsan","Erdenet","Tsetserieg",
"Baruun-Urt","Ereen","Batshireet","Choyr","Ulaangom","Tosontsengel","Atlay","Uliastay","Bayanhongor",
"Har-Ayrag","Nalayh","Tes"]
},
},*/
{
/////NEEDS NATURAL WONDERS
name:"Spanish",
@ -802,12 +802,13 @@
outerColor:[102,0,0],
innerColor:[255,102,102],
uniqueName:"Seven Cities of Gold"
unique:"Gold nous for discovering a Natural Wonder (bonus enhanced if first to discover it). Culture, Happiness and tile yelds from Natural Wonders doubled.",
unique:"100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it). Culture, Happiness and tile yelds from Natural Wonders doubled.",
cities:["Madrid","Barcelona","Seville","Cordoba","Toledo","Santiago","Salamanca","Murcia","Valencia","Zaragoza","Pamplona",
"Vitoria","Santander","Oviedo","Jaen","Logroño","Valladolid","Palma","Teruel","Almeria","Leon","Zamora","Mida",
"Lugo","Alicante","Càdiz","Eiche","Alcorcon","Burgos","Vigo","Badajoz","La Coruña","Guadalquivir","Bilbao",
"San Sebastian","Granada","Mérida","Huelva","Ibiza","Las Palmas","Tenerife"]
},
/*
{
name:"Incan",
leaderName:"Pachacuti",

View File

@ -138,5 +138,105 @@
movementCost:1,
defenceBonus: -0.1,
occursOn:["Desert"]
},
// Natural Wonders
{
name: "Barringer Crater",
type: "NaturalWonder",
gold: 2,
science: 3,
occursOn: ["Desert","Tundra"],
impassable: true,
unbuildable: true,
weight: 10
},
{
name: "Grand Mesa",
type: "NaturalWonder",
production: 2,
gold: 3,
occursOn: ["Plains","Desert","Tundra"],
impassable: true,
unbuildable: true,
weight: 10
},
{
name: "Great Barrier Reef",
type: "NaturalWonder",
food: 2,
production: 1,
gold: 1,
science: 2,
occursOn: ["Coast"],
impassable: true,
unbuildable: true,
weight: 10
},
{
name: "Krakatoa",
type: "NaturalWonder",
science: 5,
occursOn: ["Ocean"],
impassable: true,
unbuildable: true,
weight: 10
},
{
name: "Mount Fuji",
type: "NaturalWonder",
gold: 1,
culture: 5,
occursOn: ["Grassland","Plains"],
impassable: true,
unbuildable: true,
weight: 10
},
{
name: "Old Faithful",
type: "NaturalWonder",
science: 2,
happiness: 3,
occursOn: ["Grassland","Plains","Tundra","Mountain"],
impassable: true,
unbuildable: true,
weight: 10
},
{
name: "Rock of Gibraltar",
type: "NaturalWonder",
food: 2,
gold: 5,
occursOn: ["Grassland"],
impassable: true,
unbuildable: true,
weight: 10
},
{
name: "Cerro de Potosi",
type: "NaturalWonder",
gold: 10,
occursOn: ["Plains","Mountain"],
impassable: true,
unbuildable: true,
weight: 5
},
{
name: "El Dorado",
type: "NaturalWonder",
culture: 5,
occursOn: ["Plains"],
impassable: true,
unbuildable: true,
weight: 2
},
{
name: "Fountain of Youth",
type: "NaturalWonder",
happiness: 10,
occursOn: ["Plains"],
impassable: true,
unbuildable: true,
weight: 1
}
]

View File

@ -408,4 +408,9 @@
name:"Haka War Dance", // only for Maori Warrior and subsequent upgrades
effect:"-10% combat strength for adjacent enemy units"
}
{
name:"Rejuvenation", // only for Units that have been close to Natural Wonder Fountain of Youth
effect:"All healing effects doubled"
}
]

View File

@ -1145,6 +1145,29 @@ Ocean = Oceán
Flood plains = Údolní niva
Impassible = Nepřístupné
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Dobytek
@ -1449,3 +1472,5 @@ Ambush I = Přepadení I
Ambush II = Přepadení II
Haka War Dance = Haka - valečný tanec
-10% combat strength for adjacent enemy units = -10% bojové síly pro nepřátelské jednotky na sousedních políčkách
# Requires translation!
Rejuvenation =

View File

@ -1935,6 +1935,29 @@ Flood plains = Riviervlakte
# Requires translation!
Impassible =
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Rundvee
@ -2461,3 +2484,5 @@ Ambush II =
Haka War Dance =
# Requires translation!
-10% combat strength for adjacent enemy units =
# Requires translation!
Rejuvenation =

View File

@ -2181,6 +2181,29 @@ Flood plains =
# Requires translation!
Impassible =
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
# Requires translation!
@ -2766,3 +2789,5 @@ Ambush II =
Haka War Dance =
# Requires translation!
-10% combat strength for adjacent enemy units =
# Requires translation!
Rejuvenation =

View File

@ -1181,6 +1181,29 @@ Ocean = Océan
Flood plains = Plaines inondables
Impassible = Impraticable
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Bétail
@ -1490,3 +1513,5 @@ Ambush I = Embuscade I
Ambush II = Embuscade II
Haka War Dance = Haka - Danse de guerre
-10% combat strength for adjacent enemy units = -10% de force de combats pour toutes les unités ennemies adjacentes
# Requires translation!
Rejuvenation =

View File

@ -1130,6 +1130,29 @@ Ocean = Ozean
Flood plains = Flussaue
Impassible = Unpassierbar
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Rinder
@ -1431,3 +1454,5 @@ Ambush I = Lufthinterhalt I
Ambush II = Lufthinterhalt II
Haka War Dance = Haka Kriegstanz
-10% combat strength for adjacent enemy units = -10% Kampfstärke für angrenzende feindliche Einheiten
# Requires translation!
Rejuvenation =

View File

@ -1115,6 +1115,19 @@ Ocean = Oceano
Flood plains = Pianure allagate
Impassible = Inaccessibile
# Natural Wonders
Barringer Crater = Cratere di Barringer
Grand Mesa = Grand Mesa
Great Barrier Reef = Grande barriera corallina
Krakatoa = Krakatoa
Mount Fuji = Monte Fuji
Old Faithful = Old Faithful
Rock of Gibraltar = Rocca di Gibilterra
Cerro de Potosi = Cerro Rico
El Dorado = El Dorado
Fountain of Youth = Fonte della giovinezza
# Resources
Cattle = Bestiame
@ -1415,3 +1428,4 @@ Ambush I = Imboscata aerea I
Ambush II = Imboscata aerea II
Haka War Dance = Danza di guerra Haka
-10% combat strength for adjacent enemy units = -10% Forza alle unità nemiche adiacenti a questa unità
Rejuvenation = Ringiovanimento

View File

@ -1138,6 +1138,29 @@ Ocean = 대양
Flood plains = 범람원
Impassible = 지나갈 수 없음
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle =
@ -1439,3 +1462,5 @@ Ambush I = 공중 매복 I
Ambush II = 공중 매복 II
Haka War Dance = 하카 전쟁 의식
-10% combat strength for adjacent enemy units = 이 유닛과 인접한 적 유닛의 전투력 -10%
# Requires translation!
Rejuvenation =

View File

@ -1988,6 +1988,29 @@ Flood plains =
# Requires translation!
Impassible =
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
# Requires translation!
@ -2577,3 +2600,5 @@ Ambush II =
Haka War Dance =
# Requires translation!
-10% combat strength for adjacent enemy units =
# Requires translation!
Rejuvenation =

View File

@ -1525,6 +1525,29 @@ Flood plains =
# Requires translation!
Impassible =
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
# Requires translation!
@ -1883,3 +1906,5 @@ Ambush I = Zasadzka I (lotnictwo)
Ambush II = Zasadzka II (lotnictwo)
Haka War Dance = Haka - taniec wojenny
-10% combat strength for adjacent enemy units = -10% walecznej siły dla jednostek przeciwnika leżących na przyległych polach
# Requires translation!
Rejuvenation =

View File

@ -1387,6 +1387,29 @@ Ocean = Oceano
Flood plains = Planícies alagadas
Impassible = Inacessível
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Gado
@ -1689,3 +1712,5 @@ Ambush I = Emboscada Aérea I
Ambush II = Emboscada Aérea II
Haka War Dance = Dança de Guerra Haka
-10% combat strength for adjacent enemy units = -10% de força de combate para cada unidade inimiga adjacente
# Requires translation!
Rejuvenation =

View File

@ -1643,6 +1643,29 @@ Ocean = Ocean
Flood plains = Câmpii inundate
Impassible = Inaccesibil
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Vite
@ -2082,3 +2105,5 @@ Ambush II =
Haka War Dance =
# Requires translation!
-10% combat strength for adjacent enemy units =
# Requires translation!
Rejuvenation =

View File

@ -1187,6 +1187,29 @@ Ocean = Океан
Flood plains = Пойма
Impassible = Непроходимый
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Скот
@ -1504,3 +1527,5 @@ Ambush II = Засада II
Haka War Dance =
# Requires translation!
-10% combat strength for adjacent enemy units =
# Requires translation!
Rejuvenation =

View File

@ -1141,6 +1141,29 @@ Ocean = 海洋
Flood plains = 冲积平原
Impassible = 不能通行
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = 牛群
@ -1443,3 +1466,5 @@ Ambush I = 伏击I级
Ambush II = 伏击II级
Haka War Dance = 哈卡战舞
-10% combat strength for adjacent enemy units = 相邻的敌方单位-10%战斗力
# Requires translation!
Rejuvenation =

View File

@ -1642,6 +1642,29 @@ Ocean = Océano
Flood plains = Terreno inundable
Impassible = Inpasable
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Ganado
@ -2080,3 +2103,5 @@ Ambush II =
Haka War Dance =
# Requires translation!
-10% combat strength for adjacent enemy units =
# Requires translation!
Rejuvenation =

View File

@ -1126,6 +1126,29 @@ Ocean = 海洋
Flood plains = 沖積平原
Impassible = 不能通行
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = 牛群
@ -1428,3 +1451,5 @@ Ambush I = 伏擊I級
Ambush II = 伏擊II級
Haka War Dance = 哈卡戰舞
-10% combat strength for adjacent enemy units = 相鄰的敵方單位-10%戰鬥力
# Requires translation!
Rejuvenation =

View File

@ -1456,6 +1456,29 @@ Ocean = Океан
Flood plains = Заплави
Impassible = Непрохідні
# Natural Wonders
# Requires translation!
Barringer Crater =
# Requires translation!
Grand Mesa =
# Requires translation!
Great Barrier Reef =
# Requires translation!
Krakatoa =
# Requires translation!
Mount Fuji =
# Requires translation!
Old Faithful =
# Requires translation!
Rock of Gibraltar =
# Requires translation!
Cerro de Potosi =
# Requires translation!
El Dorado =
# Requires translation!
Fountain of Youth =
# Resources
Cattle = Худоба
@ -1757,3 +1780,5 @@ Ambush I = Повітряна засідка I
Ambush II = Повітряна засідка II
Haka War Dance = Бойовий танець Гака
-10% combat strength for adjacent enemy units = Сусідні ворожі підрозділи отримують силу атаки -10%
# Requires translation!
Rejuvenation =

View File

@ -1114,6 +1114,19 @@ Ocean =
Flood plains =
Impassible =
# Natural Wonders
Barringer Crater =
Grand Mesa =
Great Barrier Reef =
Krakatoa =
Mount Fuji =
Old Faithful =
Rock of Gibraltar =
Cerro de Potosi =
El Dorado =
Fountain of Youth =
# Resources
Cattle =
@ -1414,3 +1427,4 @@ Ambush I =
Ambush II =
Haka War Dance =
-10% combat strength for adjacent enemy units =
Rejuvenation =

View File

@ -17,6 +17,18 @@ class Constants{
const val grassland = "Grassland"
const val tundra = "Tundra"
const val marsh = "Marsh"
const val BarringerCrater = "Barringer Crater"
const val GrandMesa = "Grand Mesa"
const val GreatBarrierReef = "Great Barrier Reef"
const val Krakatoa = "Krakatoa"
const val MountFuji = "Mount Fuji"
const val OldFaithful = "Old Faithful"
const val RockOfGibraltar = "Rock of Gibraltar"
const val CerroDePotosi = "Cerro de Potosi"
const val ElDorado = "El Dorado"
const val FountainOfYouth = "Fountain of Youth"
const val barbarianEncampment = "Barbarian encampment"
const val ancientRuins = "Ancient ruins"

View File

@ -209,7 +209,6 @@ class CityConstructions {
civ.addNotification("[$currentConstruction] has been built in [${cityInfo.name}]", cityInfo.location, Color.BROWN)
else
civ.addNotification("[$currentConstruction] has been built in a faraway land",null,Color.BROWN)
}
} else
cityInfo.civInfo.addNotification("[$currentConstruction] has been built in [" + cityInfo.name + "]", cityInfo.location, Color.BROWN)

View File

@ -126,6 +126,12 @@ class CivInfoStats(val civInfo: CivilizationInfo){
civInfo.policies.getAdoptedPolicies().count { !it.endsWith("Complete") }.toFloat()
}
var happinessPerNaturalWonder = 1f
if (civInfo.nation.unique == "100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it). Culture, Happiness and tile yelds from Natural Wonders doubled.")
happinessPerNaturalWonder *= 2
statMap["Natural Wonders"] = happinessPerNaturalWonder * civInfo.naturalWonders.size
//From city-states
for (otherCiv in civInfo.getKnownCivs()) {
if (otherCiv.isCityState() && otherCiv.getCityStateType() == CityStateType.Mercantile

View File

@ -7,6 +7,7 @@ import com.unciv.logic.map.TileInfo
import com.unciv.models.ruleset.tile.ResourceSupplyList
import java.util.*
import kotlin.collections.HashMap
import kotlin.collections.HashSet
import kotlin.collections.set
/** CivInfo class was getting too crowded */
@ -52,18 +53,46 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo){
val viewedCivs = HashSet<CivilizationInfo>()
val viewedNaturalWonders = HashSet<TileInfo>()
for(tile in civInfo.viewableTiles){
val tileOwner = tile.getOwner()
if(tileOwner!=null) viewedCivs+=tileOwner
for(unit in tile.getUnits()) viewedCivs+=unit.civInfo
if (tile.naturalWonder != null) viewedNaturalWonders += tile
}
if(!civInfo.isBarbarian()) {
for (otherCiv in viewedCivs.filterNot { it == civInfo || it.isBarbarian() })
for (otherCiv in viewedCivs.filterNot { it == civInfo || it.isBarbarian() }) {
if (!civInfo.diplomacy.containsKey(otherCiv.civName)) {
civInfo.meetCivilization(otherCiv)
civInfo.addNotification("We have encountered ["+otherCiv.civName+"]!", null, Color.GOLD)
}
}
for (tile in viewedNaturalWonders) {
if (!civInfo.naturalWonders.contains(tile.naturalWonder)) {
civInfo.discoveryNaturalWonder(tile.naturalWonder!!)
civInfo.addNotification("We have discovered [" + tile.naturalWonder + "]!", tile.position, Color.GOLD)
var goldGained = 0
val discoveredNaturalWonders = civInfo.gameInfo.civilizations.filter { it != civInfo }.flatMap { it.naturalWonders }
if (tile.naturalWonder == "El Dorado" && !discoveredNaturalWonders.contains(tile.naturalWonder!!)) {
goldGained += 500
}
if (civInfo.nation.unique == "100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it). Culture, Happiness and tile yelds from Natural Wonders doubled.") {
if (!discoveredNaturalWonders.contains(tile.naturalWonder!!))
goldGained += 500
else
goldGained += 100
}
if (goldGained > 0) {
civInfo.gold += goldGained
civInfo.addNotification("We have received " + goldGained + " Gold for discovering [" + tile.naturalWonder + "]", null, Color.GOLD)
}
}
}
}
}

View File

@ -59,6 +59,7 @@ class CivilizationInfo {
var notifications = ArrayList<Notification>()
val popupAlerts = ArrayList<PopupAlert>()
var allyCivName = ""
var naturalWonders = ArrayList<String>()
//** for trades here, ourOffers is the current civ's offers, and theirOffers is what the requesting civ offers */
val tradeRequests = ArrayList<TradeRequest>()
@ -101,6 +102,7 @@ class CivilizationInfo {
toReturn.citiesCreated = citiesCreated
toReturn.popupAlerts.addAll(popupAlerts)
toReturn.tradeRequests.addAll(tradeRequests)
toReturn.naturalWonders.addAll(naturalWonders)
return toReturn
}
@ -258,6 +260,11 @@ class CivilizationInfo {
UncivGame.Current.settings.addCompletedTutorialTask("Meet another civilization")
}
fun discoveryNaturalWonder(naturalWonderName: String)
{
naturalWonders.add(naturalWonderName)
}
override fun toString(): String {return civName} // for debug
fun isDefeated()= cities.isEmpty() && (citiesCreated > 0 || !getCivUnits().any {it.name== Constants.settler})

View File

@ -6,8 +6,10 @@ import com.unciv.logic.HexMath
import com.unciv.models.Counter
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.tile.Terrain
import com.unciv.models.ruleset.tile.TerrainType
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.math.*
@ -49,6 +51,9 @@ class MapGenerator {
randomizeResources(map, mapRadius, ruleset)
if (!mapParameters.noNaturalWonders)
spawnNaturalWonders(map, mapRadius, ruleset)
return map
}
@ -212,6 +217,312 @@ class MapGenerator {
spreadResource(mapToReturn, distance, ResourceType.Bonus, ruleset)
}
/*
https://gaming.stackexchange.com/questions/95095/do-natural-wonders-spawn-more-closely-to-city-states/96479
https://www.reddit.com/r/civ/comments/1jae5j/information_on_the_occurrence_of_natural_wonders/
*/
fun spawnNaturalWonders(mapToReturn: TileMap, mapRadius: Int, ruleset: Ruleset) {
// number of Natural Wonders scales linearly with mapRadius as #wonders = mapRadius * 0.13133208 - 0.56128831
val numberToSpawn = round(mapRadius * 0.13133208f - 0.56128831f).toInt()
val toBeSpawned = ArrayList<Terrain>()
val allNaturalWonders = ruleset.Terrains.values.filter { it.type == TerrainType.NaturalWonder }.toMutableList()
while (allNaturalWonders.isNotEmpty() && toBeSpawned.size < numberToSpawn) {
val totalWeight = allNaturalWonders.map { it.weight }.sum().toFloat()
val x = Random().nextDouble()
var cum = 0f
for (wonder in allNaturalWonders) {
cum += wonder.weight/totalWeight
if (x <= cum) {
toBeSpawned.add(wonder)
allNaturalWonders.remove(wonder)
break
}
}
}
println("Natural Wonders for this game: ${toBeSpawned.toString()}")
for (wonder in toBeSpawned) {
when (wonder.name) {
Constants.BarringerCrater -> spawnBarringerCrater(mapToReturn, ruleset)
Constants.MountFuji -> spawnMountFuji(mapToReturn, ruleset)
Constants.GrandMesa -> spawnGrandMesa(mapToReturn, ruleset)
Constants.GreatBarrierReef -> spawnGreatBarrierReef(mapToReturn, ruleset)
Constants.Krakatoa -> spawnKrakatoa(mapToReturn, ruleset)
Constants.RockOfGibraltar -> spawnRockOfGibraltar(mapToReturn, ruleset)
Constants.OldFaithful -> spawnOldFaithful(mapToReturn, ruleset)
Constants.CerroDePotosi -> spawnCerroDePotosi(mapToReturn, ruleset)
Constants.ElDorado -> spawnElDorado(mapToReturn, ruleset)
Constants.FountainOfYouth -> spawnFountainOfYouth(mapToReturn, ruleset)
}
}
}
/*
Must be in tundra or desert; cannot be adjacent to grassland; can be adjacent to a maximum
of 2 mountains and a maximum of 4 hills and mountains; avoids oceans; becomes mountain
*/
private fun spawnBarringerCrater(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.BarringerCrater]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.none { neighbor -> neighbor.getBaseTerrain().name == Constants.grassland }
&& it.neighbors.count{ neighbor -> neighbor.getBaseTerrain().name == Constants.mountain } <= 2
&& it.neighbors.count{ neighbor -> neighbor.getBaseTerrain().name == Constants.mountain || neighbor.getBaseTerrain().name == Constants.hill} <= 4
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.mountain
location.terrainFeature = null
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
Mt. Fuji: Must be in grass or plains; cannot be adjacent to tundra, desert, marsh, or mountains;
can be adjacent to a maximum of 2 hills; becomes mountain
*/
private fun spawnMountFuji(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.MountFuji]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.none { neighbor -> neighbor.getBaseTerrain().name == Constants.tundra }
&& it.neighbors.none { neighbor -> neighbor.getBaseTerrain().name == Constants.desert }
&& it.neighbors.none { neighbor -> neighbor.getBaseTerrain().name == Constants.mountain }
&& it.neighbors.none { neighbor -> neighbor.getLastTerrain().name == Constants.marsh }
&& it.neighbors.count{ neighbor -> neighbor.getBaseTerrain().name == Constants.hill } <= 2
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.mountain
location.terrainFeature = null
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
Grand Mesa: Must be in plains, desert, or tundra, and must be adjacent to at least 2 hills;
cannot be adjacent to grass; can be adjacent to a maximum of 2 mountains; avoids oceans; becomes mountain
*/
private fun spawnGrandMesa(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.GrandMesa]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.count{ neighbor -> neighbor.getBaseTerrain().name == Constants.hill } >= 2
&& it.neighbors.none { neighbor -> neighbor.getBaseTerrain().name == Constants.grassland }
&& it.neighbors.count { neighbor -> neighbor.getBaseTerrain().name == Constants.mountain } <= 2
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.mountain
location.terrainFeature = null
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
Great Barrier Reef: Specifics currently unknown;
Assumption: at least 1 neighbour not water; no tundra; at least 1 neighbour coast; becomes coast
TODO: investigate Great Barrier Reef placement requirements
*/
private fun spawnGreatBarrierReef(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.GreatBarrierReef]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.none{ neighbor -> neighbor.getBaseTerrain().name != Constants.tundra}
&& it.neighbors.any { neighbor -> neighbor.getBaseTerrain().name != Constants.ocean
&& neighbor.getBaseTerrain().name != Constants.coast }
&& it.neighbors.any { neighbor -> neighbor.getBaseTerrain().name == Constants.coast
&& neighbor.resource == null && neighbor.improvement == null}
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.coast
location.terrainFeature = null
val location2 = location.neighbors
.filter { it.getBaseTerrain().name == Constants.coast && it.resource == null && it.improvement == null }
.random()
location2.naturalWonder = wonder.name
location2.baseTerrain = Constants.coast
location2.terrainFeature = null
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
Krakatoa: Must spawn in the ocean next to at least 1 shallow water tile; cannot be adjacent
to ice; changes tiles around it to shallow water; mountain
TODO: cannot be adjacent to ice
*/
private fun spawnKrakatoa(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.Krakatoa]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.any { neighbor -> neighbor.getBaseTerrain().name == Constants.coast }
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.mountain
location.terrainFeature = null
for (tile in location.neighbors) {
if (tile.baseTerrain == Constants.coast) continue
tile.baseTerrain = Constants.coast
tile.terrainFeature = null
tile.resource = null
tile.improvement = null
}
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
Rock of Gibraltar: Specifics currently unknown
Assumption: spawn on grassland, at least 1 coast and 1 mountain adjacent;
turn neighbours into coast)
TODO: investigate Rock of Gibraltar placement requirements
*/
private fun spawnRockOfGibraltar(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.RockOfGibraltar]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.any { neighbor -> neighbor.getBaseTerrain().name == Constants.coast }
&& it.neighbors.count { neighbor -> neighbor.getBaseTerrain().name == Constants.mountain } == 1
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.mountain
location.terrainFeature = null
for (tile in location.neighbors) {
if (tile.baseTerrain == Constants.coast) continue
if (tile.baseTerrain == Constants.mountain) continue
tile.baseTerrain = Constants.coast
tile.terrainFeature = null
tile.resource = null
tile.improvement = null
}
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
Old Faithful: Must be adjacent to at least 3 hills and mountains; cannot be adjacent to
more than 4 mountains, and cannot be adjacent to more than 3 desert or 3 tundra tiles;
avoids oceans; becomes mountain
*/
private fun spawnOldFaithful(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.OldFaithful]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.count { neighbor -> neighbor.getBaseTerrain().name == Constants.mountain } <= 4
&& it.neighbors.count { neighbor -> neighbor.getBaseTerrain().name == Constants.mountain ||
neighbor.getBaseTerrain().name == Constants.hill} >= 3
&& it.neighbors.count { neighbor -> neighbor.getBaseTerrain().name == Constants.desert } <= 3
&& it.neighbors.count { neighbor -> neighbor.getBaseTerrain().name == Constants.tundra } <= 3
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.mountain
location.terrainFeature = null
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
Cerro de Potosi: Must be adjacent to at least 1 hill; avoids oceans; becomes mountain
*/
private fun spawnCerroDePotosi(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.CerroDePotosi]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.any { neighbor -> neighbor.getBaseTerrain().name == Constants.hill }
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.mountain
location.terrainFeature = null
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
El Dorado: Must be next to at least 1 jungle tile; avoids oceans; becomes flatland plains
*/
private fun spawnElDorado(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.ElDorado]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name)
&& it.neighbors.any { neighbor -> neighbor.getLastTerrain().name == Constants.jungle }
}
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.plains
location.terrainFeature = null
}
else {
println("No suitable location for ${wonder.name}")
}
}
/*
Fountain of Youth: Avoids oceans; becomes flatland plains
*/
private fun spawnFountainOfYouth(mapToReturn: TileMap, ruleset: Ruleset) {
val wonder = ruleset.Terrains[Constants.FountainOfYouth]!!
val suitableLocations = mapToReturn.values.filter { it.resource == null && it.improvement == null
&& wonder.occursOn!!.contains(it.getLastTerrain().name) }
if (suitableLocations.isNotEmpty()) {
val location = suitableLocations.random()
location.naturalWonder = wonder.name
location.baseTerrain = Constants.plains
location.terrainFeature = null
}
else {
println("No suitable location for ${wonder.name}")
}
}
// Here, we need each specific resource to be spread over the map - it matters less if specific resources are near each other
private fun spreadStrategicResources(mapToReturn: TileMap, distance: Int, ruleset: Ruleset) {
val resourcesOfType = ruleset.TileResources.values.filter { it.resourceType == ResourceType.Strategic }

View File

@ -5,4 +5,5 @@ class MapParameters {
var type = MapType.pangaea
var radius = 20
var noRuins = false
var noNaturalWonders = false
}

View File

@ -356,6 +356,8 @@ class MapUnit {
val adjacentUnits = currentTile.getTilesInDistance(1).flatMap { it.getUnits() }
if (adjacentUnits.isNotEmpty())
amountToHealBy += adjacentUnits.map { it.adjacentHealingBonus() }.max()!!
if (hasUnique("All healing effects doubled"))
amountToHealBy *= 2
healBy(amountToHealBy)
}
@ -422,7 +424,16 @@ class MapUnit {
if(tile.improvement==Constants.barbarianEncampment && !civInfo.isBarbarian())
clearEncampment(tile)
// addPromotion requires currentTile to be valid because it accesses ruleset through it
currentTile = tile
if(!hasUnique("All healing effects doubled") && type.isLandUnit() && type.isMilitary())
{
val gainDoubleHealPromotion = tile.neighbors.filter{it.naturalWonder == "Fountain of Youth"}.any()
if (gainDoubleHealPromotion)
promotions.addPromotion("Rejuvenation", true)
}
updateVisibleTiles()
}

View File

@ -29,6 +29,7 @@ open class TileInfo {
var position: Vector2 = Vector2.Zero
lateinit var baseTerrain: String
var terrainFeature: String? = null
var naturalWonder: String? = null
var resource: String? = null
var improvement: String? = null
var improvementInProgress: String? = null
@ -48,6 +49,7 @@ open class TileInfo {
toReturn.position=position.cpy()
toReturn.baseTerrain=baseTerrain
toReturn.terrainFeature=terrainFeature
toReturn.naturalWonder=naturalWonder
toReturn.resource=resource
toReturn.improvement=improvement
toReturn.improvementInProgress=improvementInProgress
@ -81,13 +83,18 @@ open class TileInfo {
fun getCity(): CityInfo? = owningCity
fun getLastTerrain(): Terrain = if (terrainFeature == null) getBaseTerrain() else getTerrainFeature()!!
fun getLastTerrain(): Terrain = if (terrainFeature != null) getTerrainFeature()!! else if(naturalWonder != null) getNaturalWonder() else getBaseTerrain()
fun getTileResource(): TileResource =
if (resource == null) throw Exception("No resource exists for this tile!")
else ruleset.TileResources[resource!!]!!
fun getNaturalWonder() : Terrain =
if (naturalWonder == null) throw Exception("No natural wonder exists for this tile!")
else ruleset.Terrains[naturalWonder!!]!!
fun isCityCenter(): Boolean = getCity()?.location == position
fun isNaturalWonder() : Boolean = naturalWonder != null
fun getTileImprovement(): TileImprovement? = if (improvement == null) null else ruleset.TileImprovements[improvement!!]
@ -155,6 +162,16 @@ open class TileInfo {
stats.production += 1
}
if (naturalWonder != null) {
val wonder = getNaturalWonder()
stats.add(wonder)
// Spain doubles tile yield
if (city != null && city.civInfo.nation.unique == "100 Gold for discovering a Natural Wonder (bonus enhanced to 500 Gold if first to discover it). Culture, Happiness and tile yelds from Natural Wonders doubled.") {
stats.add(wonder)
}
}
if (hasViewableResource(observingCiv)) {
val resource = getTileResource()
stats.add(getTileResource()) // resource base
@ -220,8 +237,8 @@ open class TileInfo {
if(improvement.uniqueTo!=null && improvement.uniqueTo!=civInfo.civName) return false
if (improvement.techRequired != null && !civInfo.tech.isResearched(improvement.techRequired!!)) return false
val topTerrain = if (terrainFeature == null) getBaseTerrain() else getTerrainFeature()
if (improvement.terrainsCanBeBuiltOn.contains(topTerrain!!.name)) return true
val topTerrain = getLastTerrain()
if (improvement.terrainsCanBeBuiltOn.contains(topTerrain.name)) return true
if (improvement.name == "Road" && this.roadStatus === RoadStatus.None) return true
if (improvement.name == "Railroad" && this.roadStatus !== RoadStatus.Railroad) return true
@ -284,6 +301,7 @@ open class TileInfo {
lineList += baseTerrain.tr()
if (terrainFeature != null) lineList += terrainFeature!!.tr()
if (hasViewableResource(tileMap.gameInfo.getCurrentPlayerCivilization())) lineList += resource!!.tr()
if (naturalWonder != null) lineList += naturalWonder!!.tr()
if (roadStatus !== RoadStatus.None && !isCityCenter()) lineList += roadStatus.toString().tr()
if (improvement != null) lineList += improvement!!.tr()
if (improvementInProgress != null && isViewableToPlayer)

View File

@ -288,6 +288,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
if(tile.isOcean && unit.baseUnit.uniques.contains("Cannot enter ocean tiles until Astronomy")
&& !unit.civInfo.tech.isResearched("Astronomy"))
return false
if (tile.naturalWonder != null) return false
val tileOwner = tile.getOwner()
if(tileOwner!=null && tileOwner.civName!=unit.owner) {

View File

@ -0,0 +1,21 @@
package com.unciv.models.ruleset.tile
import com.unciv.models.ruleset.tr
import com.unciv.models.stats.NamedStats
import java.util.*
class NaturalWonder : NamedStats() {
fun getDescription(): String {
val stringBuilder = StringBuilder()
stringBuilder.appendln(this.clone().toString())
val terrainsCanBeBuiltOnString: ArrayList<String> = arrayListOf()
for (i in terrainsCanBeFoundOn) {
terrainsCanBeBuiltOnString.add(i.tr())
}
stringBuilder.appendln("Can be found on ".tr() + terrainsCanBeBuiltOnString.joinToString(", "))
return stringBuilder.toString()
}
var size: Int = 1
var terrainsCanBeFoundOn: List<String> = listOf()
}

View File

@ -47,6 +47,11 @@ class Terrain : NamedStats() {
*/
val occursOn: Collection<String>? = null
/*
* Natural Wonder weight: probability to be picked
*/
var weight = 10
/**
* RGB color of base terrain
*/

View File

@ -3,5 +3,6 @@ package com.unciv.models.ruleset.tile
enum class TerrainType {
Land,
Water,
TerrainFeature
TerrainFeature,
NaturalWonder
}

View File

@ -50,6 +50,11 @@ enum class UnitType{
|| this == WaterCivilian
}
fun isMilitary(): Boolean {
return this != Civilian
&& this != WaterCivilian
}
fun isWaterUnit(): Boolean {
return this==WaterSubmarine
|| this==WaterRanged

View File

@ -17,6 +17,7 @@ class MapParametersTable(val mapParameters: MapParameters): Table(){
addMapTypeSelectBox()
addWorldSizeSelectBox()
addNoRuinsCheckbox()
addNoNaturalWondersCheckbox()
}
private fun addMapTypeSelectBox() {
@ -68,4 +69,15 @@ class MapParametersTable(val mapParameters: MapParameters): Table(){
})
add(noRuinsCheckbox).colspan(2).row()
}
private fun addNoNaturalWondersCheckbox() {
val noNaturalWondersCheckbox = CheckBox("No Natural Wonders".tr(), CameraStageBaseScreen.skin)
noNaturalWondersCheckbox.isChecked = mapParameters.noNaturalWonders
noNaturalWondersCheckbox.addListener(object : ChangeListener() {
override fun changed(event: ChangeEvent?, actor: Actor?) {
mapParameters.noNaturalWonders = noNaturalWondersCheckbox.isChecked
}
})
add(noNaturalWondersCheckbox).colspan(2).row()
}
}

View File

@ -48,6 +48,7 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings)
protected var terrainFeatureOverlayImage: Image? = null
protected var terrainFeature: String? = null
protected var cityImage: Image? = null
protected var naturalWonderImage: Image? = null
protected var pixelMilitaryUnitImageLocation = ""
protected var pixelMilitaryUnitImage: Image? = null
@ -140,6 +141,13 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings)
if (ImageGetter.imageExists(tileSetStrings.cityTile))
return listOf(tileSetStrings.cityTile)
}
if (tileInfo.isNaturalWonder())
{
val naturalWonder = tileSetStrings.getTile(tileInfo.naturalWonder!!)
if (ImageGetter.imageExists(naturalWonder))
return listOf(naturalWonder)
}
val shouldShowImprovement = tileInfo.improvement!=null && UncivGame.Current.settings.showPixelImprovements
val baseTerrainTileLocation = tileSetStrings.getTile(tileInfo.baseTerrain)
if (tileInfo.terrainFeature != null) {
@ -233,6 +241,7 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings)
icons.update(showResourcesAndImprovements, tileIsViewable, showMilitaryUnit)
updateCityImage()
updateNaturalWonderImage()
updateTileColor(tileIsViewable)
updateRoadImages()
@ -281,6 +290,28 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings)
}
}
private fun updateNaturalWonderImage() {
if (naturalWonderImage == null && tileInfo.isNaturalWonder()) {
val naturalWonderOverlay = tileSetStrings.naturalWonderOverlay
if (!ImageGetter.imageExists(naturalWonderOverlay)) // Assume no natural wonder overlay = dedicated tile image
return
naturalWonderImage = ImageGetter.getImage(naturalWonderOverlay)
terrainFeatureLayerGroup.addActor(naturalWonderImage)
naturalWonderImage!!.run {
color.a = 0.25f
setSize(40f, 40f)
center(this@TileGroup)
}
}
// Is this possible?
if (naturalWonderImage != null && !tileInfo.isNaturalWonder()) {
naturalWonderImage!!.remove()
naturalWonderImage = null
}
}
var previousTileOwner: CivilizationInfo? = null
private fun updateBorderImages() {
// This is longer than it could be, because of performance -

View File

@ -11,6 +11,7 @@ class TileSetStrings {
val crosshatchHexagon = tileSetLocation+"CrosshatchHexagon"
val cityOverlay = tileSetLocation+"CityOverlay"
val railroad = tileSetLocation+"Railroad"
val naturalWonderOverlay = tileSetLocation+"NaturalWonderOverlay"
val tilesLocation = tileSetLocation+"Tiles/"
val cityTile = tilesLocation+"City"