mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-20 09:17:47 +07:00
Normalized city strength according to original civ game
Added Walls and Castle buildings
This commit is contained in:
parent
80963e7eac
commit
5fa9ad0640
@ -69,6 +69,13 @@
|
||||
hurryCostModifier:25,
|
||||
requiredTech:"Trapping"
|
||||
},
|
||||
{
|
||||
name:"Walls",
|
||||
cityStrength:5,
|
||||
cityHealth:50,
|
||||
hurryCostModifier:25,
|
||||
requiredTech:"Masonry"
|
||||
},
|
||||
{
|
||||
name:"The Pyramids",
|
||||
baseDescription: "Worker construction increased 25%, provides 2 free workers",
|
||||
@ -243,6 +250,14 @@
|
||||
requiredBuildingInAllCities:"University",
|
||||
requiredTech:"Education"
|
||||
},
|
||||
{
|
||||
name:"Castle",
|
||||
cityStrength:7,
|
||||
cityHealth:25,
|
||||
hurryCostModifier:25,
|
||||
requiredBuilding:"Walls",
|
||||
requiredTech:"Chivalry"
|
||||
},
|
||||
{
|
||||
name:"Angkor Wat",
|
||||
baseDescription: "Cost of acquiring new tiles reduced by 25%",
|
||||
|
@ -76,33 +76,32 @@ class BattleDamage{
|
||||
return modifiers
|
||||
}
|
||||
|
||||
fun getDefenceModifiers(attacker: ICombatant, defender: ICombatant): HashMap<String, Float> {
|
||||
fun getDefenceModifiers(attacker: ICombatant, defender: MapUnitCombatant): HashMap<String, Float> {
|
||||
val modifiers = getGeneralModifiers(defender, attacker)
|
||||
if (!(defender is MapUnitCombatant && defender.unit.hasUnique("No defensive terrain bonus"))) {
|
||||
if (!(defender.unit.hasUnique("No defensive terrain bonus"))) {
|
||||
val tileDefenceBonus = defender.getTile().getDefensiveBonus()
|
||||
if (tileDefenceBonus > 0) modifiers["Terrain"] = tileDefenceBonus
|
||||
}
|
||||
|
||||
if(defender is MapUnitCombatant) {
|
||||
val defenderTile = defender.getTile()
|
||||
val isDefenderInRoughTerrain = defenderTile.baseTerrain=="Hill" || defenderTile.terrainFeature == "Forest" || defenderTile.terrainFeature == "Jungle"
|
||||
for (BDM in getBattleDamageModifiersOfUnit(defender.unit)) {
|
||||
val text = BDM.getText()
|
||||
if (BDM.vs == "units in open terrain" && !isDefenderInRoughTerrain) {
|
||||
if(modifiers.containsKey(text))
|
||||
modifiers[text] =modifiers[text]!! + BDM.modificationAmount
|
||||
else modifiers[text] = BDM.modificationAmount
|
||||
}
|
||||
if (BDM.vs == "units in rough terrain" && isDefenderInRoughTerrain) {
|
||||
if (modifiers.containsKey(text))
|
||||
modifiers[text] = modifiers[text]!! + BDM.modificationAmount
|
||||
else modifiers[text] = BDM.modificationAmount
|
||||
}
|
||||
val defenderTile = defender.getTile()
|
||||
val isDefenderInRoughTerrain = defenderTile.baseTerrain == "Hill" || defenderTile.terrainFeature == "Forest" || defenderTile.terrainFeature == "Jungle"
|
||||
for (BDM in getBattleDamageModifiersOfUnit(defender.unit)) {
|
||||
val text = BDM.getText()
|
||||
if (BDM.vs == "units in open terrain" && !isDefenderInRoughTerrain) {
|
||||
if (modifiers.containsKey(text))
|
||||
modifiers[text] = modifiers[text]!! + BDM.modificationAmount
|
||||
else modifiers[text] = BDM.modificationAmount
|
||||
}
|
||||
if (BDM.vs == "units in rough terrain" && isDefenderInRoughTerrain) {
|
||||
if (modifiers.containsKey(text))
|
||||
modifiers[text] = modifiers[text]!! + BDM.modificationAmount
|
||||
else modifiers[text] = BDM.modificationAmount
|
||||
}
|
||||
}
|
||||
|
||||
if(defender is MapUnitCombatant && defender.unit.isFortified())
|
||||
modifiers["Fortification"]=0.2f*defender.unit.getFortificationTurns()
|
||||
|
||||
if (defender.unit.isFortified())
|
||||
modifiers["Fortification"] = 0.2f * defender.unit.getFortificationTurns()
|
||||
|
||||
return modifiers
|
||||
}
|
||||
@ -133,7 +132,8 @@ class BattleDamage{
|
||||
* Includes defence modifiers
|
||||
*/
|
||||
fun getDefendingStrength(attacker: ICombatant, defender: ICombatant): Float {
|
||||
val defenceModifier = modifiersToMultiplicationBonus(getDefenceModifiers(attacker,defender))
|
||||
var defenceModifier = 1f
|
||||
if(defender is MapUnitCombatant) defenceModifier = modifiersToMultiplicationBonus(getDefenceModifiers(attacker,defender))
|
||||
return defender.getDefendingStrength(attacker) * defenceModifier
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@ package com.unciv.logic.battle
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.gamebasics.unit.UnitType
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
import com.unciv.models.gamebasics.unit.UnitType
|
||||
|
||||
class CityCombatant(val city: CityInfo) : ICombatant {
|
||||
override fun getHealth(): Int = city.health
|
||||
@ -25,24 +25,29 @@ class CityCombatant(val city: CityInfo) : ICombatant {
|
||||
return getCityStrength()
|
||||
}
|
||||
|
||||
private fun
|
||||
getCityStrength(): Int {
|
||||
val baseStrength = 10
|
||||
private fun getCityStrength(): Int { // Civ fanatics forum, from a modder who went through the original code
|
||||
var strength = 8f
|
||||
if(city.isCapital()) strength+=2.5f
|
||||
strength += (city.population.population/5) * 2 // Each 5 pop gives 2 defence
|
||||
val cityTile = city.getCenterTile()
|
||||
if(cityTile.baseTerrain=="Hill") strength+=5
|
||||
// as tech progresses so does city strength
|
||||
val techsPercentKnown: Float = city.civInfo.tech.techsResearched.count().toFloat() /
|
||||
GameBasics.Technologies.count()
|
||||
val strengthFromTechs = Math.pow(techsPercentKnown*3.0,2.0) *5
|
||||
strength += Math.pow(techsPercentKnown*5.5, 2.8).toFloat()
|
||||
|
||||
// The way all of this adds up...
|
||||
// 25% of the way through the game provides an extra 3.12
|
||||
// 50% of the way through the game provides an extra 12.50
|
||||
// 75% of the way through the game provides an extra 28.12
|
||||
// All ancient techs - 0.5 extra, Classical - 2.7, Medieval - 8, Renaissance - 17.5,
|
||||
// Industrial - 32.4, Modern - 51, Atomic - 72.5, All - 118.3
|
||||
// 100% of the way through the game provides an extra 50.00
|
||||
|
||||
// 10% bonus foreach pop
|
||||
val strengthWithPop = (baseStrength + strengthFromTechs) * (1 + 0.1*city.population.population)
|
||||
// Garrisoned unit gives up to 20% of strength to city, health-dependant
|
||||
if(cityTile.militaryUnit!=null)
|
||||
strength += cityTile.militaryUnit!!.getBaseUnit().strength * cityTile.militaryUnit!!.health/100f
|
||||
|
||||
return strengthWithPop.toInt()
|
||||
strength += city.cityConstructions.getBuiltBuildings().sumBy{ it.cityStrength }
|
||||
|
||||
return strength.toInt()
|
||||
}
|
||||
|
||||
override fun toString(): String {return city.name} // for debug
|
||||
|
@ -142,15 +142,14 @@ class CityInfo {
|
||||
}
|
||||
}
|
||||
|
||||
val maxHealth =getMaxHealth()
|
||||
health = min(health+maxHealth/10, maxHealth)
|
||||
health = min(health+20, getMaxHealth())
|
||||
population.unassignExtraPopulation()
|
||||
}
|
||||
|
||||
fun isCapital() = cityConstructions.isBuilt("Palace")
|
||||
|
||||
internal fun getMaxHealth(): Int {
|
||||
return 200 // add more later when walls citadel etc.
|
||||
return 200 + cityConstructions.getBuiltBuildings().sumBy { it.cityHealth }
|
||||
}
|
||||
|
||||
override fun toString(): String {return name} // for debug
|
||||
|
@ -28,6 +28,8 @@ class Building : NamedStats(), IConstruction{
|
||||
/** City can only be built if one of these resources is nearby - it must be improved! */
|
||||
var requiredNearbyImprovedResources: List<String>? = null
|
||||
var cannotBeBuiltWith: String? = null
|
||||
var cityStrength=0
|
||||
var cityHealth=0
|
||||
|
||||
// Uniques
|
||||
var providesFreeBuilding: String? = null
|
||||
@ -52,6 +54,8 @@ class Building : NamedStats(), IConstruction{
|
||||
infoList += resourceBonusStats.toString() +" from "+improvedResources.joinToString()
|
||||
}
|
||||
if(unique!=null) infoList += unique!!
|
||||
if(cityStrength!=0) infoList+="city strength +"+cityStrength
|
||||
if(cityHealth!=0) infoList+="city health +"+cityHealth
|
||||
return infoList.joinToString()
|
||||
}
|
||||
|
||||
@ -123,6 +127,9 @@ class Building : NamedStats(), IConstruction{
|
||||
val resources = GameBasics.TileResources.values.filter { name == it.building }.joinToString { it.name }
|
||||
stringBuilder.appendln("$resources provide $resourceBonusStats")
|
||||
}
|
||||
|
||||
if(cityStrength!=0) stringBuilder.appendln("City strength +"+cityStrength)
|
||||
if(cityHealth!=0) stringBuilder.appendln("City health +"+cityHealth)
|
||||
if (maintenance != 0)
|
||||
stringBuilder.appendln("Maintenance cost: $maintenance "+"Gold".tr())
|
||||
return stringBuilder.toString().trim()
|
||||
|
@ -68,7 +68,9 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
|
||||
row().pad(5f)
|
||||
|
||||
val attackerModifiers = BattleDamage().getAttackModifiers(attacker,defender) .map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" }
|
||||
val defenderModifiers = BattleDamage().getDefenceModifiers(attacker, defender).map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" }
|
||||
val defenderModifiers = if (defender is MapUnitCombatant)
|
||||
BattleDamage().getDefenceModifiers(attacker, defender).map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" }
|
||||
else listOf()
|
||||
|
||||
for(i in 0..max(attackerModifiers.size,defenderModifiers.size)){
|
||||
if (attackerModifiers.size > i) add(attackerModifiers[i]).actor.setFont(14) else add()
|
||||
|
Loading…
Reference in New Issue
Block a user