Polynesia works!

This commit is contained in:
Yair Morgenstern 2019-10-11 14:54:08 +03:00
commit e77fdd2993
28 changed files with 734 additions and 635 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1008 KiB

After

Width:  |  Height:  |  Size: 1015 KiB

View File

@ -618,6 +618,43 @@
"Gaugamela","Harmozeia","Ekatompylos","Izata","Kampada","Kapisa","Karmana","Kounaxa","Kuganaka","Nautaka", "Gaugamela","Harmozeia","Ekatompylos","Izata","Kampada","Kapisa","Karmana","Kounaxa","Kuganaka","Nautaka",
"Paishiyauvada","Patigrbana","Phrada"] "Paishiyauvada","Patigrbana","Phrada"]
}, },
{
name:"Polynesia",
leaderName:"Kamehameha I",
adjective:["Polynesia"],
startBias:["Coast"],
preferredVictoryType:"Cultural",
startIntroPart1: "Greetings and blessings be upon you, Kamehameha the Great, chosen by the heavens to unite your scattered peoples. Oh mighty King, you were the first to bring the Big Island of Hawai'I under one solitary rule in 1791 AD. This was followed by the merging of all the remaining islands under your standard in 1810. As the first King of Hawai'I, you standardized the legal and taxation systems and instituted the Mamalahoe Kawanai, an edict protecting civilians in times of war. You ensured the continued unification and sovereignty of the islands by your strong laws and deeds, even after your death in 1819."
startIntroPart2: "Oh wise and exalted King, your people wish for a kingdom of their own once more and require a leader of unparalleled greatness! Will you answer their call and don the mantle of the Lion of the Pacific? Will you build a kingdom that stands the test of time?"
declaringWar:"The ancient fire flashing across the sky is what proclaimed that this day would come, though I had foolishly hoped for a different outcome."
attacked:"It is obvious now that I misjudged you and your true intentions."
defeated:"The hard-shelled crab yields, and the lion lies down to sleep. Kanaloa comes for me now."
introduction:"Aloha! Greetings and blessings upon you, friend. I am Kamehameha, Great King of this strand of islands."
neutralHello:"Welcome, friend!"
neutralLetsHearIt:["Proceed.","And?","What is it?"]
hateNo:["Certainly not.","We will have to decline."]
hateYes:["It is agreed, then.","Excellent!"]
hateHello:"Oh, it's you."
hateLetsHearIt:["Proceed.","I'm listening","What is it?"]
hateNo:["Certainly not!","That's not acceptable!"]
hateYes:["Yes, I suppost I must.","Yes, so be it."]
afterPeace:"Perhaps the stars were mistakenly placed... I will consult my Kahuna."
tradeRequest:"Come, let our people feast together!"
outerColor:[210,51,0],
innerColor:[255,255,78],
uniqueName:"Wayfinding"
unique:"Can embark and move over Coasts and Oceans immediately. +1 Sight when embarked. +10% Combat Strength bonus if within 2 tiles of a Moai.",
cities:["Honolulu","Samoa","Tonga","Nuku Hiva","Raiatea","Aotearoa","Tahiti","Hilo","Te Wai Pounamu","Rapa Nui",
"Tuamotu","Rarotonga","Tuvalu","Tubuai","Mangareva","Oahu","Kiritimati","Ontong Java","Niue","Rekohu",
"Rakahanga","Bora Bora","Kailua","Uvea","Futuna","Rotuma","Tokelau","Lahaina","Bellona","Mungava","Tikopia",
"Emae","Kapingamarangi","Takuu","Nukuoro","Sikaiana","Anuta","Nuguria","Pileni","Nukumanu"]
},
/* /*
@ -771,43 +808,6 @@
"Huaras","Riobamba","Caxamalca","Sausa","Tambo Colorado","Huaca","Tumbes","Chan Chan","Sipan","Pachacamac", "Huaras","Riobamba","Caxamalca","Sausa","Tambo Colorado","Huaca","Tumbes","Chan Chan","Sipan","Pachacamac",
"Llactapata","Pisac","Kuelap","Pajaten","Chucuito","Choquequirao"] "Llactapata","Pisac","Kuelap","Pajaten","Chucuito","Choquequirao"]
} }
{
name:"Polynesia",
leaderName:"Kamehameha I",
adjective:["Polynesia"],
startBias:["Coast"],
preferredVictoryType:"Cultural",
startIntroPart1: "Greetings and blessings be upon you, Kamehameha the Great, chosen by the heavens to unite your scattered peoples. Oh mighty King, you were the first to bring the Big Island of Hawai'I under one solitary rule in 1791 AD. This was followed by the merging of all the remaining islands under your standard in 1810. As the first King of Hawai'I, you standardized the legal and taxation systems and instituted the Mamalahoe Kawanai, an edict protecting civilians in times of war. You ensured the continued unification and sovereignty of the islands by your strong laws and deeds, even after your death in 1819."
startIntroPart2: "Oh wise and exalted King, your people wish for a kingdom of their own once more and require a leader of unparalleled greatness! Will you answer their call and don the mantle of the Lion of the Pacific? Will you build a kingdom that stands the test of time?"
declaringWar:"The ancient fire flashing across the sky is what proclaimed that this day would come, though I had foolishly hoped for a different outcome."
attacked:"It is obvious now that I misjudged you and your true intentions."
defeated:"The hard-shelled crab yields, and the lion lies down to sleep. Kanaloa comes for me now."
introduction:"Aloha! Greetings and blessings upon you, friend. I am Kamehameha, Great King of this strand of islands."
neutralHello:"Welcome, friend!"
neutralLetsHearIt:["Proceed.","And?","What is it?"]
hateNo:["Certainly not.","We will have to decline."]
hateYes:["It is agreed, then.","Excellent!"]
hateHello:"Oh, it's you."
hateLetsHearIt:["Proceed.","I'm listening","What is it?"]
hateNo:["Certainly not!","That's not acceptable!"]
hateYes:["Yes, I suppost I must.","Yes, so be it."]
afterPeace:"Perhaps the stars were mistakenly placed... I will consult my Kahuna."
tradeRequest:"Come, let our people feast together!"
outerColor:[210,51,0],
innerColor:[255,255,78],
uniqueName:"Wayfinding"
unique:"Can embark and move over Costs and Oceans immediately. +1 Sight when embarked",
cities:["Honolulu","Samoa","Tonga","Nuku Hiva","Raiatea","Aotearoa","Tahiti","Hilo","Te Wai Pounamu","Rapa Nui",
"Tuamotu","Rarotonga","Tuvalu","Tubuai","Mangareva","Oahu","Kiritimati","Ontong Java","Niue","Rekohu",
"Rakahanga","Bora Bora","Kailua","Uvea","Futuna","Rotuma","Tokelau","Lahaina","Bellona","Mungava","Tikopia",
"Emae","Kapingamarangi","Takuu","Nukuoro","Sikaiana","Anuta","Nuguria","Pileni","Nukumanu"]
},
{ {
name:"Songhai", name:"Songhai",
leaderName:"Askia", leaderName:"Askia",

View File

@ -155,7 +155,6 @@
techRequired:"Construction", techRequired:"Construction",
improvingTech:"Flight", improvingTech:"Flight",
improvingTechStats:{gold:1} improvingTechStats:{gold:1}
//It can be colored in orange
}, },
/* /*
{ {

View File

@ -1014,6 +1014,7 @@
} }
"'The introduction of so powerful an agent as steam to a carriage on wheels will make a great change in the situation of man.' - Thomas Jefferson":{//"Railroad" Technology quotes, it has been translated somewhere. "'The introduction of so powerful an agent as steam to a carriage on wheels will make a great change in the situation of man.' - Thomas Jefferson":{//"Railroad" Technology quotes, it has been translated somewhere.
Italian: "'L'introduzione sui carri a ruote di un agente potente come il vapore apporterà un grande cambiamento alla condizione dell'uomo.' - Thomas Jefferson"
Simplified_Chinese:"“引入蒸汽这样一个强大的助手来驱动车轮进行运输,将极大地改变人类的境地。”——托马斯·杰斐逊" Simplified_Chinese:"“引入蒸汽这样一个强大的助手来驱动车轮进行运输,将极大地改变人类的境地。”——托马斯·杰斐逊"
} }

View File

@ -402,4 +402,10 @@
effect:"Bonus vs water units 15%", effect:"Bonus vs water units 15%",
unitTypes:["WaterRanged"] unitTypes:["WaterRanged"]
} }
// Uniques
{
name:"Haka War Dance", // only for Maori Warrior and subsequent upgrades
effect:"-10% combat strength for adjacent enemy units"
}
] ]

View File

@ -39,6 +39,20 @@
upgradesTo:"Swordsman", upgradesTo:"Swordsman",
attackSound:"nonmetalhit" attackSound:"nonmetalhit"
}, },
{
name:"Maori Warrior",
unitType:"Melee",
uniqueTo:"Polynesia",
replaces:"Warrior",
movement:2,
strength:8,
cost: 40,
hurryCostModifier:20,
obsoleteTech:"Metal Casting",
promotions:["Haka War Dance"],
upgradesTo:"Swordsman",
attackSound:"nonmetalhit"
},
/* /*
{ {
name:"Jaguar", name:"Jaguar",
@ -55,21 +69,6 @@
attackSound:"nonmetalhit" attackSound:"nonmetalhit"
//Aztec unique unit, moves faster and fights better in Forest and Jungle. He also heals 25 if he kills an enemy. //Aztec unique unit, moves faster and fights better in Forest and Jungle. He also heals 25 if he kills an enemy.
}, },
{
name:"Maori Warrior",
unitType:"Melee",
uniqueTo:"Polynesia",
replaces:"Warrior",
movement:2,
strength:8,
cost: 40,
hurryCostModifier:20,
obsoleteTech:"Metal Casting",
uniques:["Haka War Dance"],
upgradesTo:"Swordsman",
attackSound:"nonmetalhit"
//Polynesian unique unit. All nearby enemy Units have -10% strenght
},
*/ */
{ {
name:"Brute", name:"Brute",

View File

@ -190,7 +190,7 @@ class GameInfo {
if(currentPlayer=="") currentPlayer=civilizations.first { it.isPlayerCivilization() }.civName if(currentPlayer=="") currentPlayer=civilizations.first { it.isPlayerCivilization() }.civName
currentPlayerCiv=getCivilization(currentPlayer) currentPlayerCiv=getCivilization(currentPlayer)
// this is separated into 2 loops because when we activate updateViewableTiles in civ.setTransients, // this is separated into 2 loops because when we activate updateVisibleTiles in civ.setTransients,
// we try to find new civs, and we check if civ is barbarian, which we can't know unless the gameInfo is already set. // we try to find new civs, and we check if civ is barbarian, which we can't know unless the gameInfo is already set.
for (civInfo in civilizations) civInfo.gameInfo = this for (civInfo in civilizations) civInfo.gameInfo = this
@ -238,7 +238,7 @@ class GameInfo {
for (civInfo in civilizations){ for (civInfo in civilizations){
for(unit in civInfo.getCivUnits()) for(unit in civInfo.getCivUnits())
unit.updateViewableTiles() // this needs to be done after all the units are assigned to their civs and all other transients are set unit.updateVisibleTiles() // this needs to be done after all the units are assigned to their civs and all other transients are set
// Since this depends on the cities of ALL civilizations, // Since this depends on the cities of ALL civilizations,
// we need to wait until we've set the transients of all the cities before we can run this. // we need to wait until we've set the transients of all the cities before we can run this.

View File

@ -74,12 +74,12 @@ class GameStarter{
val startingLocation = startingLocations[civ]!! val startingLocation = startingLocations[civ]!!
civ.placeUnitNearTile(startingLocation.position, Constants.settler) civ.placeUnitNearTile(startingLocation.position, Constants.settler)
civ.placeUnitNearTile(startingLocation.position, "Warrior") civ.placeUnitNearTile(startingLocation.position, civ.getEquivalentUnit("Warrior").name)
civ.placeUnitNearTile(startingLocation.position, "Scout") civ.placeUnitNearTile(startingLocation.position, "Scout")
if (!civ.isPlayerCivilization() && civ.isMajorCiv()) { if (!civ.isPlayerCivilization() && civ.isMajorCiv()) {
for (unit in gameInfo.getDifficulty().aiFreeUnits) { for (unit in gameInfo.getDifficulty().aiFreeUnits) {
civ.placeUnitNearTile(startingLocation.position, unit) civ.placeUnitNearTile(startingLocation.position, civ.getEquivalentUnit(unit).name)
} }
} }
} }
@ -101,13 +101,6 @@ class GameStarter{
landTilesInBigEnoughGroup.addAll(tilesInGroup) landTilesInBigEnoughGroup.addAll(tilesInGroup)
} }
for(minimumDistanceBetweenStartingLocations in tileMap.tileMatrix.size/3 downTo 0){
val freeTiles = landTilesInBigEnoughGroup
.filter { vectorIsAtLeastNTilesAwayFromEdge(it.position,minimumDistanceBetweenStartingLocations,tileMap)}
.toMutableList()
val startingLocations = HashMap<CivilizationInfo,TileInfo>()
val tilesWithStartingLocations = tileMap.values val tilesWithStartingLocations = tileMap.values
.filter { it.improvement!=null && it.improvement!!.startsWith("StartingLocation ") } .filter { it.improvement!=null && it.improvement!!.startsWith("StartingLocation ") }
@ -119,6 +112,13 @@ class GameStarter{
} // no requirements } // no requirements
} }
for(minimumDistanceBetweenStartingLocations in tileMap.tileMatrix.size/3 downTo 0){
val freeTiles = landTilesInBigEnoughGroup
.filter { vectorIsAtLeastNTilesAwayFromEdge(it.position,minimumDistanceBetweenStartingLocations,tileMap)}
.toMutableList()
val startingLocations = HashMap<CivilizationInfo,TileInfo>()
for(civ in civsOrderedByAvailableLocations){ for(civ in civsOrderedByAvailableLocations){
var startingLocation:TileInfo var startingLocation:TileInfo
val presetStartingLocation = tilesWithStartingLocations.firstOrNull { it.improvement=="StartingLocation "+civ.civName } val presetStartingLocation = tilesWithStartingLocations.firstOrNull { it.improvement=="StartingLocation "+civ.civName }

View File

@ -23,24 +23,24 @@ class Automation {
return rank return rank
} }
fun rankTileForCityWork(tile:TileInfo, city: CityInfo): Float { fun rankTileForCityWork(tile:TileInfo, city: CityInfo, foodWeight: Float = 1f): Float {
val stats = tile.getTileStats(city, city.civInfo) val stats = tile.getTileStats(city, city.civInfo)
return rankStatsForCityWork(stats, city) return rankStatsForCityWork(stats, city, foodWeight)
} }
private fun rankStatsForCityWork(stats: Stats, city: CityInfo): Float { private fun rankStatsForCityWork(stats: Stats, city: CityInfo, foodWeight: Float = 1f): Float {
var rank = 0f var rank = 0f
if(city.population.population < 5){ if(city.population.population < 5){
// "small city" - we care more about food and less about global problems like gold science and culture // "small city" - we care more about food and less about global problems like gold science and culture
rank += stats.food * 1.2f rank += stats.food * 1.2f * foodWeight
rank += stats.production rank += stats.production
rank += stats.science/2 rank += stats.science/2
rank += stats.culture/2 rank += stats.culture/2
rank += stats.gold / 5 // it's barely worth anything at this points rank += stats.gold / 5 // it's barely worth anything at this points
} }
else{ else{
if (stats.food <= 2 || city.civInfo.getHappiness() > 5) rank += (stats.food * 1.2f) //food get more value to keep city growing if (stats.food <= 2 || city.civInfo.getHappiness() > 5) rank += (stats.food * 1.2f * foodWeight) //food get more value to keep city growing
else rank += (2.4f + (stats.food - 2) / 2) // 1.2 point for each food up to 2, from there on half a point else rank += ((2.4f + (stats.food - 2) / 2) * foodWeight) // 1.2 point for each food up to 2, from there on half a point
if (city.civInfo.gold < 0 && city.civInfo.statsForNextTurn.gold <= 0) rank += stats.gold // we have a global problem if (city.civInfo.gold < 0 && city.civInfo.statsForNextTurn.gold <= 0) rank += stats.gold // we have a global problem
else rank += stats.gold / 3 // 3 gold is worse than 2 production else rank += stats.gold / 3 // 3 gold is worse than 2 production

View File

@ -2,6 +2,7 @@ package com.unciv.logic.automation
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.unciv.Constants import com.unciv.Constants
import com.unciv.UnCivGame
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.BFS import com.unciv.logic.map.BFS
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
@ -24,7 +25,7 @@ class WorkerAutomation(val unit: MapUnit) {
val tileToWork = findTileToWork() val tileToWork = findTileToWork()
if (getPriority(tileToWork, unit.civInfo) < 3) { // building roads is more important if (getPriority(tileToWork, unit.civInfo) < 3) { // building roads is more important
if (tryConnectingCities()) return if (tryConnectingCities(unit)) return
} }
if (tileToWork != currentTile) { if (tileToWork != currentTile) {
@ -41,7 +42,7 @@ class WorkerAutomation(val unit: MapUnit) {
} }
} }
if (currentTile.improvementInProgress != null) return // we're working! if (currentTile.improvementInProgress != null) return // we're working!
if (tryConnectingCities()) return //nothing to do, try again to connect cities if (tryConnectingCities(unit)) return //nothing to do, try again to connect cities
val citiesToNumberOfUnimprovedTiles = HashMap<String, Int>() val citiesToNumberOfUnimprovedTiles = HashMap<String, Int>()
for (city in unit.civInfo.cities) { for (city in unit.civInfo.cities) {
@ -53,7 +54,7 @@ class WorkerAutomation(val unit: MapUnit) {
.filter { citiesToNumberOfUnimprovedTiles[it.name]!! > 0 } .filter { citiesToNumberOfUnimprovedTiles[it.name]!! > 0 }
.sortedByDescending { citiesToNumberOfUnimprovedTiles[it.name] } .sortedByDescending { citiesToNumberOfUnimprovedTiles[it.name] }
.firstOrNull { unit.movement.canReach(it.ccenterTile) } //goto most undeveloped city .firstOrNull { unit.movement.canReach(it.ccenterTile) } //goto most undeveloped city
if (mostUndevelopedCity != null) { if (mostUndevelopedCity != null && mostUndevelopedCity != unit.currentTile.owningCity) {
val reachedTile = unit.movement.headTowards(mostUndevelopedCity.ccenterTile) val reachedTile = unit.movement.headTowards(mostUndevelopedCity.ccenterTile)
if (reachedTile != currentTile) unit.doPreTurnAction() // since we've moved, maybe we can do something here - automate if (reachedTile != currentTile) unit.doPreTurnAction() // since we've moved, maybe we can do something here - automate
return return
@ -64,7 +65,10 @@ class WorkerAutomation(val unit: MapUnit) {
private fun tryConnectingCities():Boolean { // returns whether we actually did anything private fun tryConnectingCities(unit: MapUnit):Boolean { // returns whether we actually did anything
//Player can choose not to auto-build roads & railroads.
if (unit.civInfo.isPlayerCivilization() && !UnCivGame.Current.settings.autoBuildingRoads)
return false
val targetRoad = unit.civInfo.tech.getBestRoadAvailable() val targetRoad = unit.civInfo.tech.getBestRoadAvailable()

View File

@ -265,7 +265,7 @@ class Battle(val gameInfo:GameInfo) {
capturedUnit.civInfo.removeUnit(capturedUnit) capturedUnit.civInfo.removeUnit(capturedUnit)
capturedUnit.assignOwner(attacker.getCivInfo()) capturedUnit.assignOwner(attacker.getCivInfo())
capturedUnit.updateViewableTiles() capturedUnit.updateVisibleTiles()
} }
private fun tryInterceptAirAttack(attacker:MapUnitCombatant, defender: ICombatant) { private fun tryInterceptAirAttack(attacker:MapUnitCombatant, defender: ICombatant) {

View File

@ -173,6 +173,16 @@ class BattleDamage{
if(!isFriendlyTerritory && unit.unit.hasUnique("+20% bonus outside friendly territory")) if(!isFriendlyTerritory && unit.unit.hasUnique("+20% bonus outside friendly territory"))
modifiers["Foreign Land"] = 0.2f modifiers["Foreign Land"] = 0.2f
if(unit.getCivInfo().nation.unique == "Can embark and move over Coasts and Oceans immediately. +1 Sight when embarked. +10% Combat Strength bonus if within 2 tiles of a Moai."
&& tile.getTilesInDistance(2).any { it.improvement=="Moai" })
modifiers["Moai"] = 0.1f
if(tile.neighbors.flatMap { it.getUnits() }
.any { it.hasUnique("-10% combat strength for adjacent enemy units") && it.civInfo.isAtWarWith(unit.getCivInfo()) })
modifiers["Haka War Dance"] = -0.1f
if(unit.unit.hasUnique("+33% combat bonus in Forest/Jungle") if(unit.unit.hasUnique("+33% combat bonus in Forest/Jungle")
&& (tile.terrainFeature== Constants.forest || tile.terrainFeature==Constants.jungle)) && (tile.terrainFeature== Constants.forest || tile.terrainFeature==Constants.jungle))
modifiers[tile.terrainFeature!!]=0.33f modifiers[tile.terrainFeature!!]=0.33f

View File

@ -229,11 +229,18 @@ class CityInfo {
} }
fun reassignWorkers() { fun reassignWorkers() {
var foodWeight = 1f
var foodPerTurn = 0f
while (foodWeight < 3 && foodPerTurn <= 0) {
workedTiles = hashSetOf() workedTiles = hashSetOf()
population.specialists.clear() population.specialists.clear()
for (i in 0..population.population) for (i in 0..population.population)
population.autoAssignPopulation() population.autoAssignPopulation(foodWeight)
cityStats.update() cityStats.update()
foodPerTurn = cityStats.currentCityStats.food
foodWeight += 0.5f
}
} }
fun endTurn() { fun endTurn() {

View File

@ -73,16 +73,16 @@ class PopulationManager {
// todo - change tile choice according to city! // todo - change tile choice according to city!
// if small city, favor production above all, ignore gold! // if small city, favor production above all, ignore gold!
// if larger city, food should be worth less! // if larger city, food should be worth less!
internal fun autoAssignPopulation() { internal fun autoAssignPopulation(foodWeight: Float = 1f) {
if(getFreePopulation()==0) return if(getFreePopulation()==0) return
//evaluate tiles //evaluate tiles
val bestTile: TileInfo? = cityInfo.getTiles() val bestTile: TileInfo? = cityInfo.getTiles()
.filter { it.arialDistanceTo(cityInfo.getCenterTile()) <= 3 } .filter { it.arialDistanceTo(cityInfo.getCenterTile()) <= 3 }
.filterNot { cityInfo.workedTiles.contains(it.position) || cityInfo.location==it.position} .filterNot { cityInfo.workedTiles.contains(it.position) || cityInfo.location==it.position}
.maxBy { Automation().rankTileForCityWork(it,cityInfo) } .maxBy { Automation().rankTileForCityWork(it,cityInfo, foodWeight) }
val valueBestTile = if(bestTile==null) 0f val valueBestTile = if(bestTile==null) 0f
else Automation().rankTileForCityWork(bestTile, cityInfo) else Automation().rankTileForCityWork(bestTile, cityInfo, foodWeight)
//evaluate specialists //evaluate specialists
val maxSpecialistsMap = getMaxSpecialists().toHashMap() val maxSpecialistsMap = getMaxSpecialists().toHashMap()

View File

@ -17,6 +17,7 @@ import com.unciv.logic.trade.TradeRequest
import com.unciv.models.gamebasics.* import com.unciv.models.gamebasics.*
import com.unciv.models.gamebasics.tech.TechEra import com.unciv.models.gamebasics.tech.TechEra
import com.unciv.models.gamebasics.tile.ResourceSupplyList import com.unciv.models.gamebasics.tile.ResourceSupplyList
import com.unciv.models.gamebasics.unit.BaseUnit
import com.unciv.models.stats.Stats import com.unciv.models.stats.Stats
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@ -230,6 +231,13 @@ class CivilizationInfo {
return baseBuilding return baseBuilding
} }
fun getEquivalentUnit(baseUnitName:String):BaseUnit {
for (unit in GameBasics.Units.values)
if (unit.replaces == baseUnitName && unit.uniqueTo == civName)
return unit
return GameBasics.Units[baseUnitName]!!
}
fun meetCivilization(otherCiv: CivilizationInfo) { fun meetCivilization(otherCiv: CivilizationInfo) {
diplomacy[otherCiv.civName] = DiplomacyManager(this, otherCiv.civName) diplomacy[otherCiv.civName] = DiplomacyManager(this, otherCiv.civName)
.apply { diplomaticStatus = DiplomaticStatus.Peace } .apply { diplomaticStatus = DiplomaticStatus.Peace }
@ -278,7 +286,7 @@ class CivilizationInfo {
//region state-changing functions //region state-changing functions
/** This is separate because the REGULAR setTransients updates the viewable ties, /** This is separate because the REGULAR setTransients updates the viewable ties,
* and the updateViewableTiles tries to meet civs... * and the updateVisibleTiles tries to meet civs...
* And if they civs on't yet know who they are then they don;t know if they're barbarians =\ * And if they civs on't yet know who they are then they don;t know if they're barbarians =\
* */ * */
fun setNationTransient(){ fun setNationTransient(){

View File

@ -6,7 +6,6 @@ import com.unciv.Constants
import com.unciv.logic.map.RoadStatus import com.unciv.logic.map.RoadStatus
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.tech.Technology import com.unciv.models.gamebasics.tech.Technology
import com.unciv.models.gamebasics.tr
import com.unciv.models.gamebasics.unit.BaseUnit import com.unciv.models.gamebasics.unit.BaseUnit
import com.unciv.ui.utils.withItem import com.unciv.ui.utils.withItem
import java.util.* import java.util.*
@ -202,8 +201,14 @@ class TechManager {
} }
fun updateTransientBooleans(){ fun updateTransientBooleans(){
if(researchedTechUniques.contains("Enables embarkation for land units")) unitsCanEmbark=true if(researchedTechUniques.contains("Enables embarkation for land units")
if(researchedTechUniques.contains("Enables embarked units to enter ocean tiles")) embarkedUnitsCanEnterOcean=true || civInfo.nation.unique=="Can embark and move over Coasts and Oceans immediately. +1 Sight when embarked. +10% Combat Strength bonus if within 2 tiles of a Moai.")
unitsCanEmbark=true
if(researchedTechUniques.contains("Enables embarked units to enter ocean tiles")
|| civInfo.nation.unique=="Can embark and move over Coasts and Oceans immediately. +1 Sight when embarked. +10% Combat Strength bonus if within 2 tiles of a Moai.")
embarkedUnitsCanEnterOcean=true
if(researchedTechUniques.contains("Improves movement speed on roads")) movementSpeedOnRoadsImproved = true if(researchedTechUniques.contains("Improves movement speed on roads")) movementSpeedOnRoadsImproved = true
} }

View File

@ -126,8 +126,7 @@ class MapUnit {
return getUniques().contains(unique) return getUniques().contains(unique)
} }
// we need to map all the places that this could change: Unit changes locations, owners, gets promotion? fun updateVisibleTiles() {
fun updateViewableTiles() {
if(type.isAirUnit()){ if(type.isAirUnit()){
if(hasUnique("6 tiles in every direction always visible")) if(hasUnique("6 tiles in every direction always visible"))
viewableTiles = getTile().getTilesInDistance(6) // it's that simple viewableTiles = getTile().getTilesInDistance(6) // it's that simple
@ -142,6 +141,8 @@ class MapUnit {
if (type.isWaterUnit() && !type.isCivilian() if (type.isWaterUnit() && !type.isCivilian()
&& civInfo.containsBuildingUnique("All military naval units receive +1 movement and +1 sight")) && civInfo.containsBuildingUnique("All military naval units receive +1 movement and +1 sight"))
visibilityRange += 1 visibilityRange += 1
if (isEmbarked() && civInfo.nation.unique == "Can embark and move over Coasts and Oceans immediately. +1 Sight when embarked. +10% Combat Strength bonus if within 2 tiles of a Moai.")
visibilityRange += 1
val tile = getTile() val tile = getTile()
if (tile.baseTerrain == Constants.hill && type.isLandUnit()) visibilityRange += 1 if (tile.baseTerrain == Constants.hill && type.isLandUnit()) visibilityRange += 1
@ -409,7 +410,7 @@ class MapUnit {
clearEncampment(tile) clearEncampment(tile)
currentTile = tile currentTile = tile
updateViewableTiles() updateVisibleTiles()
} }
fun putInTile(tile:TileInfo){ fun putInTile(tile:TileInfo){

View File

@ -187,6 +187,9 @@ open class TileInfo {
stats.add(improvement) // again, for the double effect stats.add(improvement) // again, for the double effect
if (containsGreatImprovement() && city != null && city.civInfo.nation.unique == "+2 Science for all specialists and Great Person tile improvements") if (containsGreatImprovement() && city != null && city.civInfo.nation.unique == "+2 Science for all specialists and Great Person tile improvements")
stats.science += 2 stats.science += 2
if(improvement.uniques.contains("+1 additional Culture for each adjacent Moai"))
stats.culture += neighbors.count{it.improvement=="Moai"}
} }
if(city!=null && isWater && city.containsBuildingUnique("+1 gold from worked water tiles in city")) if(city!=null && isWater && city.containsBuildingUnique("+1 gold from worked water tiles in city"))

View File

@ -27,9 +27,9 @@ class UnitPromotions{
unit.updateUniques() unit.updateUniques()
// Since some units get promotions upon construction, they will get the addPromotion from the unit.postBuildEvent // Since some units get promotions upon construction, they will get the addPromotion from the unit.postBuildEvent
// upon creation, BEFORE they are assigned to a tile, so the updateViewableTiles() would crash. // upon creation, BEFORE they are assigned to a tile, so the updateVisibleTiles() would crash.
// So, if the addPromotion was triggered from there, simply don't update // So, if the addPromotion was triggered from there, simply don't update
unit.updateViewableTiles() // some promotions/uniques give the unit bonus sight unit.updateVisibleTiles() // some promotions/uniques give the unit bonus sight
} }
fun getAvailablePromotions(): List<Promotion> { fun getAvailablePromotions(): List<Promotion> {

View File

@ -162,10 +162,7 @@ class BaseUnit : INamed, IConstruction, ICivilopedia {
} }
fun getDirectUpgradeUnit(civInfo: CivilizationInfo):BaseUnit{ fun getDirectUpgradeUnit(civInfo: CivilizationInfo):BaseUnit{
val uniqueUnitReplacesUpgrade: BaseUnit? = GameBasics.Units.values return civInfo.getEquivalentUnit(upgradesTo!!)
.firstOrNull{it.uniqueTo==civInfo.civName && it.replaces == upgradesTo}
if(uniqueUnitReplacesUpgrade!=null) return uniqueUnitReplacesUpgrade
return GameBasics.Units[upgradesTo!!]!!
} }
override fun toString(): String = name override fun toString(): String = name

View File

@ -17,6 +17,7 @@ class GameSettings {
var tileSet:String = "FantasyHex" var tileSet:String = "FantasyHex"
var showTutorials: Boolean = true var showTutorials: Boolean = true
var autoAssignCityProduction: Boolean = true var autoAssignCityProduction: Boolean = true
var autoBuildingRoads: Boolean = true
var showMinimap: Boolean = true var showMinimap: Boolean = true
var userName:String="" var userName:String=""

View File

@ -10,8 +10,9 @@ import com.unciv.models.gamebasics.tr
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
class NationTable(val nation: Nation, width:Float, onClick:()->Unit) class NationTable(val nation: Nation, width:Float, onClick:()->Unit)
: Table(CameraStageBaseScreen.skin){ : Table(CameraStageBaseScreen.skin) {
private val innerTable = Table() private val innerTable = Table()
init { init {
background = ImageGetter.getBackground(nation.getInnerColor()) background = ImageGetter.getBackground(nation.getInnerColor())
innerTable.pad(10f) innerTable.pad(10f)
@ -39,8 +40,16 @@ class NationTable(val nation: Nation, width:Float, onClick:()->Unit)
textList += "" textList += ""
} }
for (building in GameBasics.Buildings.values) addUniqueBuildingsText(nation, textList)
if (building.uniqueTo == nation.name) { addUniqueUnitsText(nation, textList)
addUniqueImprovementsText(nation, textList)
return textList.joinToString("\n").tr().trim().toLabel()
}
private fun addUniqueBuildingsText(nation: Nation, textList: ArrayList<String>) {
for (building in GameBasics.Buildings.values
.filter { it.uniqueTo == nation.name }) {
val originalBuilding = GameBasics.Buildings[building.replaces!!]!! val originalBuilding = GameBasics.Buildings[building.replaces!!]!!
textList += building.name.tr() + " - {replaces} " + originalBuilding.name.tr() textList += building.name.tr() + " - {replaces} " + originalBuilding.name.tr()
@ -61,9 +70,11 @@ class NationTable(val nation: Nation, width:Float, onClick:()->Unit)
textList += " {City health} " + building.cityHealth + " vs " + originalBuilding.cityHealth textList += " {City health} " + building.cityHealth + " vs " + originalBuilding.cityHealth
textList += "" textList += ""
} }
}
for (unit in GameBasics.Units.values) private fun addUniqueUnitsText(nation: Nation, textList: ArrayList<String>) {
if (unit.uniqueTo == nation.name) { for (unit in GameBasics.Units.values
.filter { it.uniqueTo == nation.name }) {
val originalUnit = GameBasics.Units[unit.replaces!!]!! val originalUnit = GameBasics.Units[unit.replaces!!]!!
textList += unit.name.tr() + " - {replaces} " + originalUnit.name.tr() textList += unit.name.tr() + " - {replaces} " + originalUnit.name.tr()
@ -81,16 +92,24 @@ class NationTable(val nation: Nation, width:Float, onClick:()->Unit)
textList += " " + "[${originalUnit.requiredResource}] not required".tr() textList += " " + "[${originalUnit.requiredResource}] not required".tr()
for (unique in unit.uniques.filterNot { it in originalUnit.uniques }) for (unique in unit.uniques.filterNot { it in originalUnit.uniques })
textList += " " + Translations.translateBonusOrPenalty(unique) textList += " " + Translations.translateBonusOrPenalty(unique)
for(unique in originalUnit.uniques.filterNot { it in unit.uniques }) for (unique in originalUnit.uniques.filterNot { it in unit.uniques })
textList += " "+"Lost ability".tr()+"(vs "+originalUnit.name.tr()+"): "+Translations.translateBonusOrPenalty(unique) textList += " " + "Lost ability".tr() + "(vs " + originalUnit.name.tr() + "): " + Translations.translateBonusOrPenalty(unique)
for (promotion in unit.promotions.filter { it !in originalUnit.promotions }) for (promotion in unit.promotions.filter { it !in originalUnit.promotions })
textList += " " + promotion.tr() + " (" + Translations.translateBonusOrPenalty(GameBasics.UnitPromotions[promotion]!!.effect) + ")" textList += " " + promotion.tr() + " (" + Translations.translateBonusOrPenalty(GameBasics.UnitPromotions[promotion]!!.effect) + ")"
textList += "" textList += ""
} }
}
private fun addUniqueImprovementsText(nation: Nation, textList: ArrayList<String>) {
for (improvement in GameBasics.TileImprovements.values
.filter { it.uniqueTo == nation.name }) {
return textList.joinToString("\n").tr().trim().toLabel() textList += improvement.name.tr()
textList += " "+improvement.clone().toString()
for(unique in improvement.uniques)
textList += " "+unique.tr()
}
} }
} }

View File

@ -43,8 +43,10 @@ class TechButton(techName:String, val techManager: TechManager, isWorldScreen: B
val techEnabledIcons = Table() val techEnabledIcons = Table()
techEnabledIcons.defaults().pad(5f) techEnabledIcons.defaults().pad(5f)
val civName = techManager.civInfo.civName
val techEnabledUnits = GameBasics.Units.values.filter { it.requiredTech == techName } val techEnabledUnits = GameBasics.Units.values.filter { it.requiredTech == techName }
val ourUniqueUnits = techEnabledUnits.filter { it.uniqueTo == techManager.civInfo.civName } val ourUniqueUnits = techEnabledUnits.filter { it.uniqueTo == civName }
val replacedUnits = ourUniqueUnits.map { it.replaces!! } val replacedUnits = ourUniqueUnits.map { it.replaces!! }
val ourEnabledUnits = techEnabledUnits.filter { it.uniqueTo == null && !replacedUnits.contains(it.name) } val ourEnabledUnits = techEnabledUnits.filter { it.uniqueTo == null && !replacedUnits.contains(it.name) }
.union(ourUniqueUnits) .union(ourUniqueUnits)
@ -53,15 +55,18 @@ class TechButton(techName:String, val techManager: TechManager, isWorldScreen: B
techEnabledIcons.add(ImageGetter.getConstructionImage(unit.name).surroundWithCircle(30f)) techEnabledIcons.add(ImageGetter.getConstructionImage(unit.name).surroundWithCircle(30f))
val techEnabledBuildings = GameBasics.Buildings.values.filter { it.requiredTech == techName } val techEnabledBuildings = GameBasics.Buildings.values.filter { it.requiredTech == techName }
val ourUniqueBuildings = techEnabledBuildings.filter { it.uniqueTo == techManager.civInfo.civName } val ourUniqueBuildings = techEnabledBuildings.filter { it.uniqueTo == civName }
val replacedBuildings = ourUniqueBuildings.map { it.replaces!! } val replacedBuildings = ourUniqueBuildings.map { it.replaces!! }
val ourEnabledBuildings = techEnabledBuildings.filter { it.uniqueTo == null && !replacedBuildings.contains(it.name) } val ourEnabledBuildings = techEnabledBuildings
.filter { it.uniqueTo == null && !replacedBuildings.contains(it.name) }
.union(ourUniqueBuildings) .union(ourUniqueBuildings)
for (building in ourEnabledBuildings) for (building in ourEnabledBuildings)
techEnabledIcons.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f)) techEnabledIcons.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f))
for (improvement in GameBasics.TileImprovements.values.filter { it.techRequired == techName || it.improvingTech == techName }) { for (improvement in GameBasics.TileImprovements.values
.filter { it.techRequired == techName || it.improvingTech == techName }
.filter { it.uniqueTo==null || it.uniqueTo==civName }) {
if (improvement.name.startsWith("Remove")) if (improvement.name.startsWith("Remove"))
techEnabledIcons.add(ImageGetter.getImage("OtherIcons/Stop")).size(30f) techEnabledIcons.add(ImageGetter.getImage("OtherIcons/Stop")).size(30f)
else techEnabledIcons.add(ImageGetter.getImprovementIcon(improvement.name, 30f)) else techEnabledIcons.add(ImageGetter.getImprovementIcon(improvement.name, 30f))

View File

@ -80,6 +80,12 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
update() update()
} }
innerTable.add("Auto-build roads".toLabel())
innerTable.addButton(if(settings.autoBuildingRoads) "Yes".tr() else "No".tr()) {
settings.autoBuildingRoads= !settings.autoBuildingRoads
update()
}
innerTable.add("Show minimap".toLabel()) innerTable.add("Show minimap".toLabel())
innerTable.addButton(if(settings.showMinimap) "Yes".tr() else "No".tr()) { innerTable.addButton(if(settings.showMinimap) "Yes".tr() else "No".tr()) {
settings.showMinimap= !settings.showMinimap settings.showMinimap= !settings.showMinimap

View File

@ -99,7 +99,7 @@ class UnitActions {
newunit.promotions.addPromotion(promotion, true) newunit.promotions.addPromotion(promotion, true)
newunit.updateUniques() newunit.updateUniques()
newunit.updateViewableTiles() newunit.updateVisibleTiles()
newunit.currentMovement = 0f newunit.currentMovement = 0f
worldScreen.shouldUpdate = true worldScreen.shouldUpdate = true
}.sound("upgrade") }.sound("upgrade")