mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-29 06:51:30 -04:00
Added German nation - #703
This commit is contained in:
parent
eb711b9a79
commit
853a325876
@ -508,6 +508,7 @@
|
||||
specialistSlots:{gold:1},
|
||||
hurryCostModifier:15,
|
||||
percentStatBonus:{gold:25},
|
||||
uniques:["+5% Production for every Trade Route with a City-State in the empire"]
|
||||
requiredBuilding:"Market",
|
||||
requiredTech:"Banking"
|
||||
},
|
||||
|
@ -430,8 +430,7 @@
|
||||
"Kolhapur","Prayaga","Ayodhya","Indraprastha","Mathura","Ujjain","Gulbarga","Jaunpur","Rajagriha","Sravasti","Tiruchirapalli","Thanjavur",
|
||||
"Bodhgaya","Kushinagar","Amaravati","Gaur","Gwalior","Jaipur","Karachi"]
|
||||
},
|
||||
/*
|
||||
{ // REQUIRES BARBARIAN CAMPS
|
||||
{
|
||||
name:"Germany",
|
||||
leaderName:"Otto von Bismark",
|
||||
adjective:["German"],
|
||||
@ -458,8 +457,8 @@
|
||||
afterPeace:"What do ye think about calling it a draw?"
|
||||
tradeRequest:"It would be in your best interest, to carefully consider this proposal."
|
||||
|
||||
mainColor:[224,224,224],
|
||||
secondaryColor:[64,64,64],
|
||||
mainColor:[150,150,150],
|
||||
secondaryColor:[60,60,60],
|
||||
uniqueName:"Furor Teutonicus"
|
||||
unique:"67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment, -25% land units maintenance.",
|
||||
cities:["Berlin","Hamburg","Munich","Cologne","Frankfurt","Essen","Dortmund","Stuttgart","Dusseldorf","Bremen",
|
||||
@ -470,6 +469,7 @@
|
||||
"Recklinghausen","Gצttingen","Wolfsburg","Koblenz","Hildesheim","Erlangen"]
|
||||
},
|
||||
|
||||
/*
|
||||
{ // REQUIRES RIVERS
|
||||
name:"Aztecs",
|
||||
leaderName:"Montezuma I",
|
||||
|
@ -362,6 +362,9 @@
|
||||
French:"Nous avons capturé un campement barbare et pillé [goldAmount] ors"
|
||||
}
|
||||
|
||||
"A barbarian [unitType] has joined us!":{
|
||||
}
|
||||
|
||||
///////////////// ruins
|
||||
|
||||
"We have found survivors in the ruins - population added to [cityName]":{
|
||||
|
@ -516,7 +516,6 @@
|
||||
attackSound:"metalhit"
|
||||
//Pikeman should upgrade not only to Musketman but also to Lancer
|
||||
},
|
||||
/*
|
||||
{
|
||||
name:"Landsknecht",
|
||||
replaces:"Pikeman",
|
||||
@ -532,7 +531,6 @@
|
||||
hurryCostModifier:20,
|
||||
attackSound:"metalhit"
|
||||
},
|
||||
*/
|
||||
{
|
||||
name:"Galleass",
|
||||
unitType:"WaterRanged",
|
||||
@ -1014,7 +1012,6 @@
|
||||
uniques:["Can move after attacking","No defensive terrain bonus"]
|
||||
hurryCostModifier:20,
|
||||
},
|
||||
/*
|
||||
{
|
||||
name:"Panzer",
|
||||
unitType:"Armor",
|
||||
@ -1029,7 +1026,6 @@
|
||||
hurryCostModifier:20,
|
||||
//German unique unit, stronger than Tank
|
||||
},
|
||||
*/
|
||||
{
|
||||
name:"Anti-Tank Gun",
|
||||
unitType:"Melee",
|
||||
|
@ -85,6 +85,16 @@ class Battle(val gameInfo:GameInfo) {
|
||||
conquerCity(defender.city, attacker)
|
||||
}
|
||||
|
||||
|
||||
// German unique - needs to be checked before we try to move to the enemy tile, since the encampment disappears after we move in
|
||||
if(defender.isDefeated() && defender.getCivInfo().isBarbarianCivilization() && attackedTile.improvement==Constants.barbarianEncampment
|
||||
&& attacker.getCivInfo().getNation().unique== "67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment, -25% land units maintenance."
|
||||
&& Random().nextDouble() > 0.67){
|
||||
attacker.getCivInfo().placeUnitNearTile(attackedTile.position, defender.getName())
|
||||
attacker.getCivInfo().gold += 25
|
||||
attacker.getCivInfo().addNotification("A barbarian [${defender.getName()}] has joined us!",attackedTile.position, Color.RED)
|
||||
}
|
||||
|
||||
// we're a melee unit and we destroyed\captured an enemy unit
|
||||
else if (attacker.isMelee()
|
||||
&& (defender.isDefeated() || defender.getCivInfo()==attacker.getCivInfo())
|
||||
@ -96,6 +106,7 @@ class Battle(val gameInfo:GameInfo) {
|
||||
attacker.unit.moveToTile(attackedTile)
|
||||
}
|
||||
|
||||
|
||||
if(attacker is MapUnitCombatant) {
|
||||
val unit = attacker.unit
|
||||
if (unit.hasUnique("Can move after attacking")
|
||||
@ -141,6 +152,7 @@ class Battle(val gameInfo:GameInfo) {
|
||||
addXp(defender,2,attacker)
|
||||
}
|
||||
|
||||
|
||||
// Add culture when defeating a barbarian when Honor policy is adopted (can be either attacker or defender!)
|
||||
fun tryGetCultureFromHonor(civUnit:ICombatant, barbarianUnit:ICombatant){
|
||||
if(barbarianUnit.isDefeated() && barbarianUnit is MapUnitCombatant
|
||||
|
@ -49,8 +49,8 @@ class CityConstructions {
|
||||
|
||||
fun getStatPercentBonuses(): Stats {
|
||||
val stats = Stats()
|
||||
for (building in getBuiltBuildings().filter { it.percentStatBonus != null })
|
||||
stats.add(building.percentStatBonus!!)
|
||||
for (building in getBuiltBuildings())
|
||||
stats.add(building.getStatPercentageBonuses(cityInfo.civInfo))
|
||||
return stats
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ import kotlin.math.min
|
||||
|
||||
class CityInfo {
|
||||
@Transient lateinit var civInfo: CivilizationInfo
|
||||
@Transient var isConnectedToCapital = false
|
||||
@Transient lateinit var ccenterTile:TileInfo // cached for better performance
|
||||
@Transient val range = 2
|
||||
@Transient lateinit var tileMap: TileMap
|
||||
@ -95,7 +94,6 @@ class CityInfo {
|
||||
toReturn.tiles = tiles
|
||||
toReturn.workedTiles = workedTiles
|
||||
toReturn.isBeingRazed=isBeingRazed
|
||||
toReturn.isConnectedToCapital = isConnectedToCapital
|
||||
toReturn.attackedThisTurn = attackedThisTurn
|
||||
toReturn.resistanceCounter = resistanceCounter
|
||||
return toReturn
|
||||
@ -178,6 +176,7 @@ class CityInfo {
|
||||
}
|
||||
|
||||
fun isCapital() = cityConstructions.isBuilt("Palace")
|
||||
fun isConnectedToCapital() = civInfo.citiesConnectedToCapital.contains(this)
|
||||
|
||||
internal fun getMaxHealth(): Int {
|
||||
return 200 + cityConstructions.getBuiltBuildings().sumBy { it.cityHealth }
|
||||
|
@ -34,7 +34,7 @@ class CityStats {
|
||||
|
||||
private fun getStatsFromTradeRoute(): Stats {
|
||||
val stats = Stats()
|
||||
if (!cityInfo.isCapital() && isConnectedToCapital(RoadStatus.Road)) {
|
||||
if (!cityInfo.isCapital() && cityInfo.isConnectedToCapital()) {
|
||||
val civInfo = cityInfo.civInfo
|
||||
var goldFromTradeRoute = civInfo.getCapital().population.population * 0.15 + cityInfo.population.population * 1.1 - 1 // Calculated by http://civilization.wikia.com/wiki/Trade_route_(Civ5)
|
||||
if(civInfo.getNation().unique=="+1 Gold from each Trade Route, Oil resources provide double quantity") goldFromTradeRoute += 1
|
||||
@ -196,7 +196,7 @@ class CityStats {
|
||||
happinessFromPolicies += (cityInfo.population.population / 10).toFloat()
|
||||
if (civInfo.policies.isAdopted("Monarchy") && cityInfo.isCapital())
|
||||
happinessFromPolicies += (cityInfo.population.population / 2).toFloat()
|
||||
if (civInfo.policies.isAdopted("Meritocracy") && isConnectedToCapital(RoadStatus.Road))
|
||||
if (civInfo.policies.isAdopted("Meritocracy") && cityInfo.isConnectedToCapital())
|
||||
happinessFromPolicies += 1f
|
||||
if(civInfo.policies.isAdopted("Military Caste") && cityInfo.getCenterTile().militaryUnit!=null)
|
||||
happinessFromPolicies+=1
|
||||
@ -320,7 +320,7 @@ class CityStats {
|
||||
fun isConnectedToCapital(roadType: RoadStatus): Boolean {
|
||||
if (cityInfo.civInfo.cities.count() < 2) return false// first city!
|
||||
|
||||
if(roadType==RoadStatus.Road) return cityInfo.isConnectedToCapital // this transient is not applicable to connection via railroad.
|
||||
if(roadType==RoadStatus.Road) return cityInfo.isConnectedToCapital() // this transient is not applicable to connection via railroad.
|
||||
|
||||
val capitalTile = cityInfo.civInfo.getCapital().getCenterTile()
|
||||
val bfs = BFS(capitalTile){it.roadStatus == roadType}
|
||||
|
7
core/src/com/unciv/logic/civilization/CityStateType.kt
Normal file
7
core/src/com/unciv/logic/civilization/CityStateType.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package com.unciv.logic.civilization
|
||||
|
||||
enum class CityStateType{
|
||||
Cultured,
|
||||
Maritime,
|
||||
Mercantile
|
||||
}
|
@ -14,7 +14,7 @@ import com.unciv.logic.map.BFS
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.trade.Trade
|
||||
import com.unciv.logic.trade.TradeRequest
|
||||
import com.unciv.models.gamebasics.*
|
||||
import com.unciv.models.gamebasics.tech.TechEra
|
||||
import com.unciv.models.gamebasics.tile.ResourceSupplyList
|
||||
@ -25,24 +25,10 @@ import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
enum class PlayerType{
|
||||
AI,
|
||||
Human
|
||||
}
|
||||
|
||||
enum class CityStateType{
|
||||
Cultured,
|
||||
Maritime,
|
||||
Mercantile
|
||||
}
|
||||
|
||||
class TradeRequest(val requestingCiv:String,
|
||||
/** Their offers are what they offer us, and our offers are what they want in return */
|
||||
val trade: Trade)
|
||||
|
||||
class CivilizationInfo {
|
||||
@Transient lateinit var gameInfo: GameInfo
|
||||
/**
|
||||
@ -53,6 +39,8 @@ class CivilizationInfo {
|
||||
@Transient private var units=listOf<MapUnit>()
|
||||
@Transient var viewableTiles = setOf<TileInfo>()
|
||||
@Transient var viewableInvisibleUnitsTiles = setOf<TileInfo>()
|
||||
/** Contains cities from ALL civilizations connected by trade routes to the capital */
|
||||
@Transient var citiesConnectedToCapital = listOf<CityInfo>()
|
||||
|
||||
/** This is for performance since every movement calculation depends on this, see MapUnit comment */
|
||||
@Transient var hasActiveGreatWall = false
|
||||
@ -203,9 +191,16 @@ class CivilizationInfo {
|
||||
val freeUnits = 3
|
||||
var unitsToPayFor = getCivUnits()
|
||||
if(policies.isAdopted("Oligarchy")) unitsToPayFor = unitsToPayFor.filterNot { it.getTile().isCityCenter() }
|
||||
val totalPaidUnits = max(0,unitsToPayFor.count()-freeUnits)
|
||||
|
||||
var numberOfUnitsToPayFor = max(0f, unitsToPayFor.count().toFloat() - freeUnits)
|
||||
if(getNation().unique=="67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment, -25% land units maintenance."){
|
||||
val numberOfUnitsWithDiscount = min(numberOfUnitsToPayFor, unitsToPayFor.count { it.type.isLandUnit() }.toFloat())
|
||||
numberOfUnitsToPayFor -= 0.25f * numberOfUnitsWithDiscount
|
||||
}
|
||||
|
||||
|
||||
val gameProgress = gameInfo.turns/400f // as game progresses Maintenance cost rises
|
||||
var cost = baseUnitCost*totalPaidUnits*(1+gameProgress)
|
||||
var cost = baseUnitCost*numberOfUnitsToPayFor*(1+gameProgress)
|
||||
cost = cost.pow(1+gameProgress/3) // Why 3? To spread 1 to 1.33
|
||||
if(!isPlayerCivilization())
|
||||
cost *= gameInfo.getDifficulty().aiUnitMaintenanceModifier
|
||||
@ -544,6 +539,7 @@ class CivilizationInfo {
|
||||
val citiesReachedToMediums = HashMap<CityInfo,ArrayList<String>>()
|
||||
var citiesToCheck = mutableListOf(getCapital())
|
||||
citiesReachedToMediums[getCapital()] = arrayListOf("Start")
|
||||
|
||||
while(citiesToCheck.isNotEmpty() && citiesReachedToMediums.size<cities.size){
|
||||
val newCitiesToCheck = mutableListOf<CityInfo>()
|
||||
for(cityToConnectFrom in citiesToCheck){
|
||||
@ -551,6 +547,7 @@ class CivilizationInfo {
|
||||
|
||||
// This is copypasta and can be cleaned up
|
||||
if(!reachedMediums.contains("Road")){
|
||||
|
||||
val roadBfs = BFS(cityToConnectFrom.getCenterTile()){it.roadStatus!=RoadStatus.None}
|
||||
roadBfs.stepToEnd()
|
||||
val reachedCities = cities.filter { roadBfs.tilesReached.containsKey(it.getCenterTile())}
|
||||
@ -586,9 +583,7 @@ class CivilizationInfo {
|
||||
citiesToCheck = newCitiesToCheck
|
||||
}
|
||||
|
||||
for(city in cities){
|
||||
city.isConnectedToCapital = citiesReachedToMediums.containsKey(city)
|
||||
}
|
||||
citiesConnectedToCapital = citiesReachedToMediums.keys.toList()
|
||||
}
|
||||
|
||||
fun destroy(){
|
||||
|
6
core/src/com/unciv/logic/civilization/PlayerType.kt
Normal file
6
core/src/com/unciv/logic/civilization/PlayerType.kt
Normal file
@ -0,0 +1,6 @@
|
||||
package com.unciv.logic.civilization
|
||||
|
||||
enum class PlayerType{
|
||||
AI,
|
||||
Human
|
||||
}
|
@ -39,3 +39,8 @@ class Trade{
|
||||
theirOffers.addAll(trade.theirOffers)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TradeRequest(val requestingCiv:String,
|
||||
/** Their offers are what they offer us, and our offers are what they want in return */
|
||||
val trade: Trade)
|
@ -55,10 +55,9 @@ class Building : NamedStats(), IConstruction{
|
||||
val infoList= mutableListOf<String>()
|
||||
val str = getStats(null).toString()
|
||||
if(str.isNotEmpty()) infoList += str
|
||||
if(percentStatBonus!=null){
|
||||
for(stat in percentStatBonus!!.toHashMap())
|
||||
for(stat in getStatPercentageBonuses(null).toHashMap())
|
||||
if(stat.value!=0f) infoList+="+${stat.value.toInt()}% ${stat.key.toString().tr()}"
|
||||
}
|
||||
|
||||
val improvedResources = GameBasics.TileResources.values.filter { it.building==name }.map { it.name.tr() }
|
||||
if(improvedResources.isNotEmpty()){
|
||||
// buildings that improve resources
|
||||
@ -93,13 +92,14 @@ class Building : NamedStats(), IConstruction{
|
||||
if(uniques.isNotEmpty()) stringBuilder.appendln(uniques.asSequence().map { it.tr() }.joinToString("\n"))
|
||||
if (stats.toString() != "")
|
||||
stringBuilder.appendln(stats)
|
||||
if (this.percentStatBonus != null) {
|
||||
if (this.percentStatBonus!!.production != 0f) stringBuilder.append("+" + this.percentStatBonus!!.production.toInt() + "% {Production}\n".tr())
|
||||
if (this.percentStatBonus!!.gold != 0f) stringBuilder.append("+" + this.percentStatBonus!!.gold.toInt() + "% {Gold}\n".tr())
|
||||
if (this.percentStatBonus!!.science != 0f) stringBuilder.append("+" + this.percentStatBonus!!.science.toInt() + "% {Science}\r\n".tr())
|
||||
if (this.percentStatBonus!!.food != 0f) stringBuilder.append("+" + this.percentStatBonus!!.food.toInt() + "% {Food}\n".tr())
|
||||
if (this.percentStatBonus!!.culture != 0f) stringBuilder.append("+" + this.percentStatBonus!!.culture.toInt() + "% {Culture}\r\n".tr())
|
||||
}
|
||||
|
||||
val percentStats = getStatPercentageBonuses(civInfo)
|
||||
if (percentStats.production != 0f) stringBuilder.append("+" + percentStats.production.toInt() + "% {Production}\n".tr())
|
||||
if (percentStats.gold != 0f) stringBuilder.append("+" + percentStats.gold.toInt() + "% {Gold}\n".tr())
|
||||
if (percentStats.science != 0f) stringBuilder.append("+" + percentStats.science.toInt() + "% {Science}\r\n".tr())
|
||||
if (percentStats.food != 0f) stringBuilder.append("+" + percentStats.food.toInt() + "% {Food}\n".tr())
|
||||
if (percentStats.culture != 0f) stringBuilder.append("+" + percentStats.culture.toInt() + "% {Culture}\r\n".tr())
|
||||
|
||||
if (this.greatPersonPoints != null) {
|
||||
val gpp = this.greatPersonPoints!!
|
||||
if (gpp.production != 0f) stringBuilder.appendln("+" + gpp.production.toInt()+" " + "[Great Engineer] points".tr())
|
||||
@ -143,12 +143,6 @@ class Building : NamedStats(), IConstruction{
|
||||
if (adoptedPolicies.contains("Humanism") && hashSetOf("University", "Observatory", "Public School").contains(baseBuildingName ))
|
||||
stats.happiness += 1f
|
||||
|
||||
if (adoptedPolicies.contains("Theocracy") && baseBuildingName == "Temple")
|
||||
percentStatBonus = Stats().apply { gold = 10f }
|
||||
|
||||
if (adoptedPolicies.contains("Free Thought") && baseBuildingName == "University")
|
||||
percentStatBonus!!.science = 50f
|
||||
|
||||
if (adoptedPolicies.contains("Rationalism Complete") && !isWonder && stats.science > 0)
|
||||
stats.gold += 1f
|
||||
|
||||
@ -168,6 +162,26 @@ class Building : NamedStats(), IConstruction{
|
||||
return stats
|
||||
}
|
||||
|
||||
fun getStatPercentageBonuses(civInfo: CivilizationInfo?): Stats {
|
||||
val stats = percentStatBonus
|
||||
if(stats==null) return Stats() // empty
|
||||
if(civInfo==null) return stats // initial stats
|
||||
|
||||
val adoptedPolicies = civInfo.policies.adoptedPolicies
|
||||
val baseBuildingName = getBaseBuilding().name
|
||||
|
||||
if (adoptedPolicies.contains("Theocracy") && baseBuildingName == "Temple")
|
||||
stats.gold = 10f
|
||||
|
||||
if (adoptedPolicies.contains("Free Thought") && baseBuildingName == "University")
|
||||
stats.science = 50f
|
||||
|
||||
if(uniques.contains("+5% Production for every Trade Route with a City-State in the empire"))
|
||||
stats.production += 5*civInfo.citiesConnectedToCapital.count { it.civInfo.isCityState() }
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
override fun canBePurchased(): Boolean {
|
||||
return !isWonder && !isNationalWonder
|
||||
}
|
||||
@ -331,7 +345,7 @@ class Building : NamedStats(), IConstruction{
|
||||
|
||||
fun isStatRelated(stat: Stat): Boolean {
|
||||
if (get(stat) > 0) return true
|
||||
if (percentStatBonus!=null && percentStatBonus!!.get(stat)>0) return true
|
||||
if (getStatPercentageBonuses(null).get(stat)>0) return true
|
||||
if (specialistSlots!=null && specialistSlots!!.get(stat)>0) return true
|
||||
return false
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ class NationTable(val nation: Nation, val newGameParameters: GameParameters, ski
|
||||
for (stat in building.toHashMap())
|
||||
if (stat.value != originalBuildingStatMap[stat.key])
|
||||
textList += " "+stat.key.toString().tr() +" "+stat.value.toInt() + " vs " + originalBuildingStatMap[stat.key]!!.toInt()
|
||||
|
||||
for(unique in building.uniques.filter { it !in originalBuilding.uniques })
|
||||
textList += " "+unique.tr()
|
||||
if (building.maintenance != originalBuilding.maintenance)
|
||||
@ -74,6 +75,8 @@ class NationTable(val nation: Nation, val newGameParameters: GameParameters, ski
|
||||
val originalUnit = GameBasics.Units[unit.replaces!!]!!
|
||||
|
||||
textList += unit.name.tr() + " - {replaces} " + originalUnit.name.tr()
|
||||
if(unit.cost != originalUnit.cost)
|
||||
textList += " {Cost} " + unit.cost + " vs " + originalUnit.cost
|
||||
if (unit.strength != originalUnit.strength)
|
||||
textList += " {Strength} " + unit.strength + " vs " + originalUnit.strength
|
||||
if (unit.rangedStrength!= originalUnit.rangedStrength)
|
||||
|
@ -12,7 +12,6 @@ import com.unciv.UnCivGame
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.SpecialConstruction
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.ui.cityscreen.CityScreen
|
||||
import com.unciv.ui.utils.*
|
||||
|
||||
@ -87,7 +86,7 @@ class CityButton(val city: CityInfo, internal val tileGroup: WorldTileGroup, ski
|
||||
val starImage = ImageGetter.getImage("OtherIcons/Star.png").apply { color = Color.LIGHT_GRAY }
|
||||
iconTable.add(starImage).size(20f).pad(2f).padLeft(10f)
|
||||
}
|
||||
} else if (city.civInfo.isCurrentPlayer() && city.cityStats.isConnectedToCapital(RoadStatus.Road)) {
|
||||
} else if (city.civInfo.isCurrentPlayer() && city.isConnectedToCapital()) {
|
||||
val connectionImage = ImageGetter.getStatIcon("CityConnection")
|
||||
iconTable.add(connectionImage).size(20f).pad(2f).padLeft(10f)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user