scenario editing mode improvements and new unique (#2999)

* scenario editing mode improvements and new uniques

* Fixed Russian nation unique - it is civ-wide bonus

* genericized "+[]% Production when building [] in this city"

* genericized "All newly-trained [] units in this city receive the [] promotion"

* changed some uniques to be able to have list of filters separated by comma as unique param

* scenario editing mode improvements:

Resource requirements when buying buildings and units are ignored

Limit for selling buildings is ignored

Workers improve tiles instantly

Units will not be disbanded if civilization has negative gold

* fix crash in scenario editing mode due to PerpetualConstruction not having a GoldCost

* undo comma separation

* implement All newly-trained [relevant] units in this city receive the [] promotion
relevant as in 'units that can receive'

* upadte template.properties

* unnecessary parentheses

* Not being annoyed by this vs less chance of forgetting to set gold before releasing scenario

* update template.properties

* add missing spaces
This commit is contained in:
HadeanLake 2020-08-18 19:20:59 +03:00 committed by GitHub
parent 18834d94ae
commit 764a1c3913
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 47 additions and 16 deletions

View file

@ -158,7 +158,7 @@
"culture": 1, "culture": 1,
"isWonder": true, "isWonder": true,
"uniques": ["+15% Combat Strength for all units when attacking Cities"], "uniques": ["+15% Combat Strength for all units when attacking Cities"],
"requiredTech": "Bronze Working" "requiredTech": "Bronze Working",
"quote": "'He spoke, the son of Kronos, and nodded his head with the dark brows, and the immortally anointed hair of the great god swept from his divine head, and all Olympos was shaken' - The Iliad" "quote": "'He spoke, the son of Kronos, and nodded his head with the dark brows, and the immortally anointed hair of the great god swept from his divine head, and all Olympos was shaken' - The Iliad"
}, },
{ {
@ -167,8 +167,8 @@
"greatPersonPoints": {"gold": 1}, "greatPersonPoints": {"gold": 1},
"isWonder": true, "isWonder": true,
"uniques": ["Provides a sum of gold each time you spend a Great Person", "uniques": ["Provides a sum of gold each time you spend a Great Person",
"[+2 Gold] from [Marble] tiles in this city", "[+2 Gold] from [Stone] tiles in this city"] "[+2 Gold] from [Marble] tiles in this city", "[+2 Gold] from [Stone] tiles in this city"],
"requiredTech": "Masonry" "requiredTech": "Masonry",
"quote": "'The whole earth is the tomb of heroic men and their story is not given only on stone over their clay but abides everywhere without visible symbol woven into the stuff of other men's lives.' - Pericles" "quote": "'The whole earth is the tomb of heroic men and their story is not given only on stone over their clay but abides everywhere without visible symbol woven into the stuff of other men's lives.' - Pericles"
}, },
@ -179,7 +179,7 @@
"hurryCostModifier": 25, "hurryCostModifier": 25,
"maintenance": 1, "maintenance": 1,
"resourceBonusStats": {"food": 1}, "resourceBonusStats": {"food": 1},
"uniques": ["Can only be built in coastal cities", "[+1 Food] from [Ocean] tiles in this city", "[+1 Food] from [Coast] tiles in this city"] "uniques": ["Can only be built in coastal cities", "[+1 Food] from [Ocean] tiles in this city", "[+1 Food] from [Coast] tiles in this city"],
"requiredTech": "Optics" "requiredTech": "Optics"
}, },
{ {
@ -198,7 +198,7 @@
"requiredNearbyImprovedResources": ["Horses","Sheep","Cattle"], "requiredNearbyImprovedResources": ["Horses","Sheep","Cattle"],
"resourceBonusStats": {"production": 1}, "resourceBonusStats": {"production": 1},
"hurryCostModifier": 25, "hurryCostModifier": 25,
"uniques": ["+15% Production when building Mounted Units in this city"], "uniques": ["+[15]% production when building [mounted units] in this city"],
"requiredTech": "Horseback Riding" "requiredTech": "Horseback Riding"
}, },
{ {
@ -421,7 +421,7 @@
"requiredNearbyImprovedResources": ["Iron"], "requiredNearbyImprovedResources": ["Iron"],
"resourceBonusStats": {"production": 1}, "resourceBonusStats": {"production": 1},
"requiredTech": "Metal Casting", "requiredTech": "Metal Casting",
"uniques": ["+15% production of land units", "Increases production of spaceship parts by 15%"] "uniques": ["+[15]% production when building [land units] in this city", "+[15]% production when building [Spaceship part] in this city"]
}, },
{ {
"name": "Harbor", "name": "Harbor",
@ -499,7 +499,7 @@
"isWonder": true, "isWonder": true,
"providesFreeBuilding": "Castle", "providesFreeBuilding": "Castle",
"percentStatBonus": {"culture": 20}, "percentStatBonus": {"culture": 20},
"uniques": ["All newly-trained melee, mounted, and armored units in this city receive the Drill I promotion"], "uniques": ["All newly-trained [relevant] units in this city receive the [Drill I] promotion"],
"requiredTech": "Chivalry", "requiredTech": "Chivalry",
"quote": "'Justice is an unassailable fortress, built on the brow of a mountain which cannot be overthrown by the violence of torrents, nor demolished by the force of armies.' - Joseph Addison" "quote": "'Justice is an unassailable fortress, built on the brow of a mountain which cannot be overthrown by the violence of torrents, nor demolished by the force of armies.' - Joseph Addison"
}, },
@ -659,7 +659,7 @@
"maintenance": 2, "maintenance": 2,
"requiredBuilding": "Harbor", "requiredBuilding": "Harbor",
"uniques": ["+1 production and gold from all sea resources worked by the city", "uniques": ["+1 production and gold from all sea resources worked by the city",
"Can only be built in coastal cities", "+15% production of naval units"], "Can only be built in coastal cities", "+[15]% production when building [naval units] in this city"],
"requiredTech": "Navigation" "requiredTech": "Navigation"
}, },
{ {
@ -900,7 +900,7 @@
"production": 3, "production": 3,
"requiredResource": "Aluminum", "requiredResource": "Aluminum",
"cost": 360, "cost": 360,
"uniques": ["Increases production of spaceship parts by 50%"], "uniques": ["+[50]% production when building [Spaceship part] in this city"],
"requiredBuilding": "Factory", "requiredBuilding": "Factory",
"requiredTech": "Robotics" "requiredTech": "Robotics"
}, },
@ -927,7 +927,7 @@
"greatPersonPoints": {"science": 1}, "greatPersonPoints": {"science": 1},
"providesFreeBuilding": "Spaceship Factory", "providesFreeBuilding": "Spaceship Factory",
"uniques": ["2 free great scientists appear", "uniques": ["2 free great scientists appear",
"Increases production of spaceship parts by 25%"], "+[25]% production when building [Spaceship part] in this city"],
"requiredTech": "Satellites", "requiredTech": "Satellites",
"quote": "'The wonder is, not that the field of stars is so vast, but that man has measured it.' - Anatole France" "quote": "'The wonder is, not that the field of stars is so vast, but that man has measured it.' - Anatole France"
}, },

View file

@ -195,7 +195,7 @@
"innerColor": [0,0,0], "innerColor": [0,0,0],
"unique": "SIBERIAN_RICHES", "unique": "SIBERIAN_RICHES",
"uniqueName": "Siberian Riches", "uniqueName": "Siberian Riches",
"uniques": ["[+1 Production] from [Strategic resource] tiles in this city","Double quantity of [Horses] produced", "uniques": ["[+1 Production] from every [Strategic resource]","Double quantity of [Horses] produced",
"Double quantity of [Iron] produced","Double quantity of [Uranium] produced"] "Double quantity of [Iron] produced","Double quantity of [Uranium] produced"]
"cities": ["Moscow","St. Petersburg","Novgorod","Rostov","Yaroslavl","Yekaterinburg","Yakutsk","Vladivostok","Smolensk","Orenburg", "cities": ["Moscow","St. Petersburg","Novgorod","Rostov","Yaroslavl","Yekaterinburg","Yakutsk","Vladivostok","Smolensk","Orenburg",
"Krasnoyarsk","Khabarovsk","Bryansk","Tver","Novosibirsk","Magadan","Murmansk","Irkutsk","Chita","Samara", "Krasnoyarsk","Khabarovsk","Bryansk","Tver","Novosibirsk","Magadan","Murmansk","Irkutsk","Chita","Samara",

View file

@ -685,6 +685,10 @@ Buildings =
# For the "when constructing [military units]" translation # For the "when constructing [military units]" translation
military units = military units =
melee units = melee units =
mounted units =
naval units =
# For the All "newly-trained [relevant] units in this city receive the [] promotion" translation. Relevant as in 'units that can receive'
relevant =
Wonders = Wonders =
Base values = Base values =
Bonuses = Bonuses =

View file

@ -288,6 +288,7 @@ class CityStats {
val stats = cityInfo.cityConstructions.getStatPercentBonuses() val stats = cityInfo.cityConstructions.getStatPercentBonuses()
val currentConstruction = cityInfo.cityConstructions.getCurrentConstruction() val currentConstruction = cityInfo.cityConstructions.getCurrentConstruction()
// This is to be deprecated and converted to "+[]% production when building [] in this city" - keeping it here to that mods with this can still work for now
if (currentConstruction is Building && currentConstruction.uniques.contains("Spaceship part")) { if (currentConstruction is Building && currentConstruction.uniques.contains("Spaceship part")) {
if (cityInfo.containsBuildingUnique("Increases production of spaceship parts by 15%")) if (cityInfo.containsBuildingUnique("Increases production of spaceship parts by 15%"))
stats.production += 15 stats.production += 15
@ -297,6 +298,7 @@ class CityStats {
stats.production += 50 stats.production += 50
} }
// This is to be deprecated and converted to "+[]% production when building [] in this city" - keeping it here to that mods with this can still work for now
if (currentConstruction is BaseUnit) { if (currentConstruction is BaseUnit) {
if (currentConstruction.unitType == UnitType.Mounted if (currentConstruction.unitType == UnitType.Mounted
&& cityInfo.containsBuildingUnique("+15% Production when building Mounted Units in this city")) && cityInfo.containsBuildingUnique("+15% Production when building Mounted Units in this city"))
@ -309,6 +311,20 @@ class CityStats {
stats.production += 15 stats.production += 15
} }
for (unique in cityInfo.cityConstructions.builtBuildingUniqueMap.getUniques("+[]% production when building [] in this city")) {
val filter = unique.params[1]
if (currentConstruction.name == filter
|| (filter == "land units" && currentConstruction is BaseUnit && currentConstruction.unitType.isLandUnit())
|| (filter == "naval units" && currentConstruction is BaseUnit && currentConstruction.unitType.isWaterUnit())
|| (filter == "mounted units" && currentConstruction is BaseUnit && currentConstruction.unitType == UnitType.Mounted)
|| (filter == "military units" && currentConstruction is BaseUnit && currentConstruction.unitType.isMilitary())
|| (filter == "melee units" && currentConstruction is BaseUnit && currentConstruction.unitType.isMelee())
|| (filter == "Buildings" && currentConstruction is Building && !currentConstruction.isWonder)
|| (filter == "Wonders" && currentConstruction is Building && currentConstruction.isWonder)
|| (currentConstruction is Building && currentConstruction.uniques.contains(filter)))
stats.production += unique.params[0].toInt()
}
return stats return stats
} }

View file

@ -367,7 +367,7 @@ class MapUnit {
private fun workOnImprovement() { private fun workOnImprovement() {
val tile = getTile() val tile = getTile()
tile.turnsToImprovement -= 1 tile.turnsToImprovement -= 1
if (tile.turnsToImprovement != 0) return if (tile.turnsToImprovement != 0 && !civInfo.gameInfo.gameParameters.godMode) return
if (civInfo.isCurrentPlayer()) if (civInfo.isCurrentPlayer())
UncivGame.Current.settings.addCompletedTutorialTask("Construct an improvement") UncivGame.Current.settings.addCompletedTutorialTask("Construct an improvement")

View file

@ -307,7 +307,7 @@ class Building : NamedStats(), IConstruction {
if (cannotBeBuiltWith != null && construction.isBuilt(cannotBeBuiltWith!!)) if (cannotBeBuiltWith != null && construction.isBuilt(cannotBeBuiltWith!!))
return "Cannot be built with $cannotBeBuiltWith" return "Cannot be built with $cannotBeBuiltWith"
if (requiredResource != null && !civInfo.hasResource(requiredResource!!)) if (requiredResource != null && !civInfo.hasResource(requiredResource!!) && !civInfo.gameInfo.gameParameters.godMode)
return "Consumes 1 [$requiredResource]" return "Consumes 1 [$requiredResource]"
if (requiredNearbyImprovedResources != null) { if (requiredNearbyImprovedResources != null) {

View file

@ -136,7 +136,7 @@ class BaseUnit : INamed, IConstruction {
&& uniques.contains("Requires Manhattan Project")) return "Disabled by setting" && uniques.contains("Requires Manhattan Project")) return "Disabled by setting"
if (uniques.contains("Requires Manhattan Project") && !civInfo.hasUnique("Enables nuclear weapon")) if (uniques.contains("Requires Manhattan Project") && !civInfo.hasUnique("Enables nuclear weapon"))
return "Requires Manhattan Project" return "Requires Manhattan Project"
if (requiredResource!=null && !civInfo.hasResource(requiredResource!!)) return "Consumes 1 [$requiredResource]" if (requiredResource!=null && !civInfo.hasResource(requiredResource!!) && !civInfo.gameInfo.gameParameters.godMode) return "Consumes 1 [$requiredResource]"
if (name == Constants.settler && civInfo.isCityState()) return "No settler for city-states" if (name == Constants.settler && civInfo.isCityState()) return "No settler for city-states"
if (name == Constants.settler && civInfo.isOneCityChallenger()) return "No settler for players in One City Challenge" if (name == Constants.settler && civInfo.isOneCityChallenger()) return "No settler for players in One City Challenge"
return "" return ""
@ -164,6 +164,17 @@ class BaseUnit : INamed, IConstruction {
XP += unique.params[0].toInt() XP += unique.params[0].toInt()
unit.promotions.XP = XP unit.promotions.XP = XP
for (unique in construction.cityInfo.cityConstructions.builtBuildingUniqueMap.getUniques("All newly-trained [] units in this city receive the [] promotion")) {
val filter = unique.params[0]
val promotion = unique.params[1]
if (unit.name == filter
|| (filter == "relevant" && civInfo.gameInfo.ruleSet.unitPromotions.values.any { unit.type.toString() in it.unitTypes && it.name == promotion })
|| unit.type.name == filter
|| uniques.contains(filter))
unit.promotions.addPromotion(promotion, isFree = true)
}
// This is to be deprecated and converted to "All newly-trained [] in this city receive the [] promotion" - keeping it here to that mods with this can still work for now
if (unit.type in listOf(UnitType.Melee,UnitType.Mounted,UnitType.Armor) if (unit.type in listOf(UnitType.Melee,UnitType.Mounted,UnitType.Armor)
&& construction.cityInfo.containsBuildingUnique("All newly-trained melee, mounted, and armored units in this city receive the Drill I promotion")) && construction.cityInfo.containsBuildingUnique("All newly-trained melee, mounted, and armored units in this city receive the Drill I promotion"))
unit.promotions.addPromotion("Drill I", isFree = true) unit.promotions.addPromotion("Drill I", isFree = true)

View file

@ -114,7 +114,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(CameraStageBaseS
cityScreen.update() cityScreen.update()
}).open() }).open()
} }
if (cityScreen.city.hasSoldBuildingThisTurn || cityScreen.city.isPuppet if ((cityScreen.city.hasSoldBuildingThisTurn && !cityScreen.city.civInfo.gameInfo.gameParameters.godMode) || cityScreen.city.isPuppet
|| !UncivGame.Current.worldScreen.isPlayersTurn) || !UncivGame.Current.worldScreen.isPlayersTurn)
sellBuildingButton.disable() sellBuildingButton.disable()
} }

View file

@ -327,7 +327,7 @@ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScre
val button = "".toTextButton() val button = "".toTextButton()
if (construction == null || (!construction.canBePurchased() && !city.civInfo.gameInfo.gameParameters.godMode) if (construction == null || construction is PerpetualConstruction || (!construction.canBePurchased() && !city.civInfo.gameInfo.gameParameters.godMode)
) { ) {
// fully disable a "buy" button only for "priceless" buildings such as wonders // fully disable a "buy" button only for "priceless" buildings such as wonders
// for all other cases, the price should be displayed // for all other cases, the price should be displayed