Updated Autocracy branch to G&K (#4149)

* Updated Autocracy branch to G&K

* Fxied a typo

* Implemented potentially requested changes

* Implemented requested changes

Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
Xander Lenstra 2021-06-18 08:46:30 +02:00 committed by GitHub
parent 1d18c418e7
commit d1c10c6d47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 100 additions and 44 deletions

View File

@ -101,7 +101,7 @@
{
"name": "Discipline",
"uniques":["+[15]% Strength for [Melee] units which have another [Military] unit in an adjacent tile"],
"row": 1,
"row": 1,
"column": 4
},
{
@ -393,7 +393,7 @@
{
"name": "Autocracy",
"era": "Industrial era",
"uniques": ["-33% unit upkeep costs"],
"uniques": ["-[33]% unit upkeep costs", "Upon capturing a city, receive [10] times its [Culture] production as [Culture] immediately"],
"policies": [
{
"name": "Populism",
@ -403,13 +403,13 @@
},
{
"name": "Militarism",
"uniques": ["Gold cost of purchasing units -33%"],
"uniques": ["Gold cost of purchasing [All] units -[33]%"],
"row": 1,
"column": 5
},
{
"name": "Fascism",
"uniques": ["Quantity of strategic resources produced by the empire increased by 100%"],
"uniques": ["Quantity of strategic resources produced by the empire +[100]%", "+[2] Movement for all [Great General] units"],
"requires": ["Populism","Militarism"],
"row": 2,
"column": 3
@ -417,20 +417,21 @@
{
"name": "Police State",
"uniques": ["[+3 Happiness] from every [Courthouse]", "+[100]% Production when constructing [Courthouse]"],
// There are also some uniques regarding espoinage, which as of this writing is not yet implemented
"requires": ["Militarism"],
"row": 2,
"column": 5
},
{
"name": "Total War",
"uniques": ["+[15]% Production when constructing [Military] units [in all cities]", "New [Military] units start with [15] Experience"],
"uniques": ["+[25]% Production when constructing [Military] units [in all cities]", "New [Military] units start with [15] Experience"],
"requires": ["Police State","Fascism"],
"row": 3,
"column": 4
},
{
"name": "Autocracy Complete",
"uniques": ["+20% attack bonus to all Military Units for 30 turns"]
"uniques": ["+[25]% attack strength to all [Military] units for [50] turns"]
}
]
}

View File

@ -10,6 +10,7 @@ import com.unciv.logic.map.TileInfo
import com.unciv.models.AttackableTile
import com.unciv.models.ruleset.Unique
import com.unciv.models.ruleset.unit.UnitType
import com.unciv.models.stats.Stat
import java.util.*
import kotlin.math.max
@ -317,6 +318,13 @@ object Battle {
return
}
for (unique in attackerCiv.getMatchingUniques("Upon capturing a city, receive [] times its [] production as [] immediately")) {
attackerCiv.addStat(
Stat.valueOf(unique.params[2]),
unique.params[0].toInt() * city.cityStats.currentCityStats.get(Stat.valueOf(unique.params[1])).toInt()
)
}
if (attackerCiv.isPlayerCivilization()) {
attackerCiv.popupAlerts.add(PopupAlert(AlertType.CityConquered, city.id))
UncivGame.Current.settings.addCompletedTutorialTask("Conquer a city")

View File

@ -147,8 +147,11 @@ object BattleDamage {
}
}
if (attacker.getCivInfo().policies.autocracyCompletedTurns > 0)
modifiers["Autocracy Complete"] = 20
for (unique in attacker.getCivInfo().getMatchingUniques("+[]% attack strength to all [] units for [] turns")) {
if (attacker.matchesCategory(unique.params[1])) {
modifiers.add("Temporary Bonus", unique.params[0].toInt())
}
}
if (defender is CityCombatant &&
attacker.getCivInfo()

View File

@ -34,7 +34,7 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
for (unique in civInfo.getMatchingUniques("-[]% [] unit maintenance costs")) {
val numberOfUnitsWithDiscount = min(numberOfUnitsToPayFor, unitsToPayFor.count { it.matchesFilter(unique.params[1]) }.toFloat())
numberOfUnitsToPayFor -= numberOfUnitsWithDiscount * unique.params[0].toFloat() / 100
numberOfUnitsToPayFor -= numberOfUnitsWithDiscount * unique.params[0].toFloat() / 100f
}
val turnLimit = BASE_GAME_DURATION_TURNS * civInfo.gameInfo.gameParameters.gameSpeed.modifier
@ -43,11 +43,11 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
cost = cost.pow(1 + gameProgress / 3) // Why 3? To spread 1 to 1.33
if (!civInfo.isPlayerCivilization())
cost *= civInfo.gameInfo.getDifficulty().aiUnitMaintenanceModifier
for (unique in civInfo.getMatchingUniques("-[]% unit upkeep costs")) {
cost *= 1f - unique.params[0].toFloat() / 100f
}
// Deprecated since 3.15
if (civInfo.hasUnique("-33% unit upkeep costs")) cost *= 0.67f
//

View File

@ -19,6 +19,7 @@ import com.unciv.models.ruleset.tile.ResourceSupplyList
import com.unciv.models.ruleset.tile.ResourceType
import com.unciv.models.ruleset.tile.TileResource
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats
import com.unciv.models.translations.tr
import com.unciv.ui.victoryscreen.RankingType
@ -92,6 +93,11 @@ class CivilizationInfo {
/** See DiplomacyManager.flagsCountdown to why not eEnum */
private var flagsCountdown = HashMap<String, Int>()
/** Arraylist instead of HashMap as there might be doubles
* Pairs of Uniques and the amount of turns they are still active
* If the counter reaches 0 at the end of a turn, it is removed immediately
*/
var temporaryUniques = ArrayList<Pair<Unique, Int>>()
// if we only use lists, and change the list each time the cities are changed,
// we won't get concurrent modification exceptions.
@ -135,6 +141,7 @@ class CivilizationInfo {
toReturn.naturalWonders.addAll(naturalWonders)
toReturn.cityStatePersonality = cityStatePersonality
toReturn.flagsCountdown.putAll(flagsCountdown)
toReturn.temporaryUniques.addAll(temporaryUniques)
return toReturn
}
@ -213,15 +220,21 @@ class CivilizationInfo {
}
fun getResourceModifier(resource: TileResource): Int {
var resourceModifier = 1
var resourceModifier = 1f
for (unique in getMatchingUniques("Double quantity of [] produced"))
if (unique.params[0] == resource.name)
resourceModifier *= 2
resourceModifier *= 2f
if (resource.resourceType == ResourceType.Strategic) {
if (hasUnique("Quantity of strategic resources produced by the empire increased by 100%"))
resourceModifier *= 2
resourceModifier *= 1f + getMatchingUniques("Quantity of strategic resources produced by the empire +[]%")
.map { it.params[0].toFloat() / 100f }.sum()
// Deprecated since 3.15
if (hasUnique("Quantity of strategic resources produced by the empire increased by 100%")) {
resourceModifier *= 2f
}
//
}
return resourceModifier
return resourceModifier.toInt()
}
fun hasResource(resourceName: String): Boolean = getCivResourcesByName()[resourceName]!! > 0
@ -242,7 +255,8 @@ class CivilizationInfo {
} +
policies.policyUniques.getUniques(uniqueTemplate) +
tech.getTechUniques().filter { it.placeholderText == uniqueTemplate } +
religionManager.getUniques().filter { it.placeholderText == uniqueTemplate }
religionManager.getUniques().filter { it.placeholderText == uniqueTemplate } +
temporaryUniques.filter { it.first.placeholderText == uniqueTemplate }.map { it.first }
}
//region Units
@ -547,6 +561,12 @@ class CivilizationInfo {
for (city in cities.toList()) { // a city can be removed while iterating (if it's being razed) so we need to iterate over a copy
city.endTurn()
}
// Update turn counter for temporary uniques
for (unique in temporaryUniques.toList()) {
temporaryUniques.remove(unique)
if (unique.second > 1) temporaryUniques.add(Pair(unique.first, unique.second - 1))
}
goldenAges.endTurn(getHappiness())
getCivUnits().forEach { it.endTurn() }
@ -566,6 +586,18 @@ class CivilizationInfo {
else -> gold + delta
}
}
fun addStat(stat: Stat, amount: Int) {
when (stat) {
Stat.Culture -> policies.addCulture(amount)
Stat.Science -> tech.addScience(amount)
Stat.Gold -> addGold(amount)
Stat.Faith -> religionManager.storedFaith += amount
else -> {}
// Food and Production wouldn't make sense to be added nationwide
// Happiness cannot be added as it is recalculated again, use a unique instead
}
}
fun getGreatPersonPointsForNextTurn(): Stats {
val stats = Stats()

View File

@ -27,11 +27,13 @@ class PolicyManager {
private var cultureBuildingsAdded = HashMap<String, String>() // Maps cities to buildings
private var specificBuildingsAdded = HashMap<String, MutableSet<String>>() // Maps buildings to cities
@Deprecated("Deprecated since 3.15")
var autocracyCompletedTurns = 0
@Deprecated("Deprecated since 3.14.17") // Replaced with cultureBuildingsAdded
var legalismState = HashMap<String, String>() // Maps cities to buildings
// We make it a reference copy of the original variable. This way, it can still works in older versions
fun clone(): PolicyManager {
val toReturn = PolicyManager()
@ -42,11 +44,11 @@ class PolicyManager {
toReturn.storedCulture = storedCulture
toReturn.cultureBuildingsAdded.putAll(cultureBuildingsAdded)
toReturn.specificBuildingsAdded.putAll(specificBuildingsAdded)
toReturn.autocracyCompletedTurns = autocracyCompletedTurns
// Deprecated since 3.14.17, left for backwards compatibility
toReturn.legalismState.putAll(cultureBuildingsAdded)
// Deprecated since 3.15 left for backwards compatibility
toReturn.legalismState.putAll(cultureBuildingsAdded)
toReturn.autocracyCompletedTurns = autocracyCompletedTurns
//
return toReturn
}
@ -89,8 +91,6 @@ class PolicyManager {
fun endTurn(culture: Int) {
addCulture(culture)
if (autocracyCompletedTurns > 0)
autocracyCompletedTurns -= 1
}
// from https://forums.civfanatics.com/threads/the-number-crunching-thread.389702/
@ -166,7 +166,7 @@ class PolicyManager {
if (!canAdoptPolicy()) shouldOpenPolicyPicker = false
}
fun tryToAddPolicyBuildings() {
tryAddCultureBuildings()
tryAddFreeBuildings()
@ -188,10 +188,10 @@ class PolicyManager {
for (city in candidateCities) {
val builtBuilding = city.cityConstructions.addCultureBuilding()
if (builtBuilding != null) cultureBuildingsAdded[city.id] = builtBuilding!!
}
}
private fun tryAddFreeBuildings() {
val matchingUniques = civInfo.getMatchingUniques("Immediately creates a [] in each of your first [] cities for free")
// If we have "create a free aqueduct in first 3 cities" and "create free aqueduct in first 4 cities", we do: "create free aqueduct in first 3+4=7 cities"
@ -200,7 +200,7 @@ class PolicyManager {
tryAddSpecificBuilding(unique.key, unique.value.sumBy {it.params[1].toInt()})
}
}
private fun tryAddSpecificBuilding(building: String, cityCount: Int) {
if (specificBuildingsAdded[building] == null) specificBuildingsAdded[building] = mutableSetOf()
val citiesAlreadyGivenBuilding = specificBuildingsAdded[building]
@ -211,13 +211,13 @@ class PolicyManager {
.filter {
it.id !in citiesAlreadyGivenBuilding && !it.cityConstructions.containsBuildingOrEquivalent(building)
}
for (city in candidateCities) {
city.cityConstructions.getConstruction(building).postBuildEvent(city.cityConstructions, false)
citiesAlreadyGivenBuilding.add(city.id)
citiesAlreadyGivenBuilding.add(city.id)
}
}
fun getListOfFreeBuildings(cityId: String): MutableSet<String> {
val freeBuildings = cultureBuildingsAdded.filter { it.key == cityId }.values.toMutableSet()
for (building in specificBuildingsAdded.filter { it.value.contains(cityId) }) {
@ -225,4 +225,4 @@ class PolicyManager {
}
return freeBuildings
}
}
}

View File

@ -329,7 +329,7 @@ class MapUnit {
val unitToUpgradeTo = getUnitToUpgradeTo()
var goldCostOfUpgrade = (unitToUpgradeTo.cost - baseUnit().cost) * 2f + 10f
for (unique in civInfo.getMatchingUniques("Gold cost of upgrading [] units reduced by []%")) {
if (matchesFilter(unique.params[0]))
if (matchesFilter(unique.params[0]))
goldCostOfUpgrade *= (1 - unique.params[1].toFloat() / 100f)
}
// Deprecated since 3.14.17
@ -337,7 +337,7 @@ class MapUnit {
goldCostOfUpgrade *= 0.67f
}
//
if (goldCostOfUpgrade < 0) return 0 // For instance, Landsknecht costs less than Spearman, so upgrading would cost negative gold
return goldCostOfUpgrade.toInt()
}

View File

@ -85,7 +85,10 @@ object UniqueTriggerActivation {
"[] Free Technologies" -> if (!civInfo.isSpectator()) civInfo.tech.freeTechs += unique.params[0].toInt()
"Quantity of strategic resources produced by the empire increased by 100%" -> civInfo.updateDetailedCivResources()
"+20% attack bonus to all Military Units for 30 turns" -> civInfo.policies.autocracyCompletedTurns = 30
// Deprecated since 3.15
"+20% attack bonus to all Military Units for 30 turns" -> civInfo.temporaryUniques.add(Pair(unique, 30))
//
"+[]% attack strength to all [] Units for [] turns" -> civInfo.temporaryUniques.add(Pair(unique, unique.params[2].toInt()))
"Reveals the entire map" -> civInfo.exploredTiles.addAll(civInfo.gameInfo.tileMap.values.asSequence().map { it.position })
@ -94,12 +97,13 @@ object UniqueTriggerActivation {
val promotion = unique.params[1]
for (unit in civInfo.getCivUnits())
if (unit.matchesFilter(filter)
|| civInfo.gameInfo.ruleSet.unitPromotions.values.any {
it.name == promotion && unit.type.name in it.unitTypes
})
|| civInfo.gameInfo.ruleSet.unitPromotions.values.any {
it.name == promotion && unit.type.name in it.unitTypes
}
) {
unit.promotions.addPromotion(promotion, isFree = true)
}
}
}
}
}

View File

@ -112,10 +112,18 @@ class BaseUnit : INamed, IConstruction {
override fun getGoldCost(civInfo: CivilizationInfo): Int {
var cost = getBaseGoldCost(civInfo)
if (civInfo.hasUnique("Gold cost of purchasing units -33%")) cost *= 0.66f
for (unique in civInfo.getMatchingUniques("Gold cost of purchasing [] units -[]%")) {
if (matchesFilter(unique.params[0]))
cost *= 1f - unique.params[1].toFloat() / 100f
}
// Deprecated since 3.15
if (civInfo.hasUnique("Gold cost of purchasing units -33%")) cost *= 0.67f
//
for (unique in civInfo.getMatchingUniques("Cost of purchasing items in cities reduced by []%"))
cost *= 1 - (unique.params[0].toFloat() / 100)
return (cost / 10).toInt() * 10 // rounded down o nearest ten
cost *= 1f - (unique.params[0].toFloat() / 100f)
return (cost / 10).toInt() * 10 // rounded down to nearest ten
}
fun getDisbandGold(civInfo: CivilizationInfo) = getBaseGoldCost(civInfo).toInt() / 20