Better main menu map

This commit is contained in:
Yair Morgenstern 2023-01-23 20:14:54 +02:00
parent 5bec368452
commit 291237a2eb
5 changed files with 100 additions and 100 deletions

View File

@ -11,6 +11,7 @@ import com.unciv.logic.GameStarter
import com.unciv.logic.UncivShowableException
import com.unciv.logic.map.MapParameters
import com.unciv.logic.map.MapShape
import com.unciv.logic.map.MapSize
import com.unciv.logic.map.MapSizeNew
import com.unciv.logic.map.MapType
import com.unciv.logic.map.mapgenerator.MapGenerator
@ -122,8 +123,9 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
val newMap = MapGenerator(mapRuleset)
.generateMap(MapParameters().apply {
shape = MapShape.rectangular
mapSize = MapSizeNew(mapWidth.toInt() + 1, mapHeight.toInt() + 1)
mapSize = MapSizeNew(MapSize.Small)
type = MapType.pangaea
temperatureExtremeness = 1f
waterThreshold = -0.1f // mainly land, gets about 30% water
modifyForEasterEgg()
})

View File

@ -2,7 +2,6 @@ package com.unciv.logic.map.mapunit
import com.badlogic.gdx.math.Vector2
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.IsPartOfGameInfoSerialization
import com.unciv.logic.automation.unit.UnitAutomation
import com.unciv.logic.automation.unit.WorkerAutomation
@ -10,10 +9,8 @@ import com.unciv.logic.battle.Battle
import com.unciv.logic.battle.MapUnitCombatant
import com.unciv.logic.city.City
import com.unciv.logic.civilization.Civilization
import com.unciv.logic.civilization.LocationAction
import com.unciv.logic.civilization.NotificationCategory
import com.unciv.logic.civilization.NotificationIcon
import com.unciv.logic.map.tile.RoadStatus
import com.unciv.logic.map.tile.Tile
import com.unciv.models.UnitActionType
import com.unciv.models.helpers.UnitMovementMemoryType
@ -28,7 +25,6 @@ import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.ruleset.unit.UnitType
import com.unciv.models.stats.Stats
import com.unciv.ui.utils.extensions.filterAndLogic
import com.unciv.ui.utils.extensions.toPercent
import java.text.DecimalFormat
import kotlin.math.pow
@ -586,74 +582,6 @@ class MapUnit : IsPartOfGameInfoSerialization {
if (isExploring()) UnitAutomation.automatedExplore(this)
}
internal fun workOnImprovement() {
val tile = getTile()
if (tile.isMarkedForCreatesOneImprovement()) return
tile.turnsToImprovement -= 1
if (tile.turnsToImprovement != 0) return
if (civInfo.isCurrentPlayer())
UncivGame.Current.settings.addCompletedTutorialTask("Construct an improvement")
when {
tile.improvementInProgress!!.startsWith(Constants.remove) -> {
val removedFeatureName = tile.improvementInProgress!!.removePrefix(Constants.remove)
val tileImprovement = tile.getTileImprovement()
if (tileImprovement != null
&& tile.terrainFeatures.any {
tileImprovement.terrainsCanBeBuiltOn.contains(it) && it == removedFeatureName
}
&& !tileImprovement.terrainsCanBeBuiltOn.contains(tile.baseTerrain)
) {
// We removed a terrain (e.g. Forest) and the improvement (e.g. Lumber mill) requires it!
tile.changeImprovement(null)
if (tile.resource != null) civInfo.cache.updateCivResources() // unlikely, but maybe a mod makes a resource improvement dependent on a terrain feature
}
if (RoadStatus.values().any { tile.improvementInProgress == it.removeAction }) {
tile.removeRoad()
} else {
val removedFeatureObject = tile.ruleset.terrains[removedFeatureName]
if (removedFeatureObject != null && removedFeatureObject.hasUnique(UniqueType.ProductionBonusWhenRemoved)) {
tryProvideProductionToClosestCity(removedFeatureName)
}
tile.removeTerrainFeature(removedFeatureName)
}
}
tile.improvementInProgress == RoadStatus.Road.name -> tile.addRoad(RoadStatus.Road, this.civInfo)
tile.improvementInProgress == RoadStatus.Railroad.name -> tile.addRoad(RoadStatus.Railroad, this.civInfo)
tile.improvementInProgress == Constants.repair -> tile.setRepaired()
else -> {
val improvement = civInfo.gameInfo.ruleSet.tileImprovements[tile.improvementInProgress]!!
improvement.handleImprovementCompletion(this)
tile.changeImprovement(tile.improvementInProgress)
}
}
tile.improvementInProgress = null
tile.getCity()?.updateCitizens = true
}
private fun tryProvideProductionToClosestCity(removedTerrainFeature: String) {
val tile = getTile()
val closestCity = civInfo.cities.minByOrNull { it.getCenterTile().aerialDistanceTo(tile) }
@Suppress("FoldInitializerAndIfToElvis")
if (closestCity == null) return
val distance = closestCity.getCenterTile().aerialDistanceTo(tile)
var productionPointsToAdd = if (distance == 1) 20 else 20 - (distance - 2) * 5
if (tile.owningCity == null || tile.owningCity!!.civInfo != civInfo) productionPointsToAdd =
productionPointsToAdd * 2 / 3
if (productionPointsToAdd > 0) {
closestCity.cityConstructions.addProductionPoints(productionPointsToAdd)
val locations = LocationAction(tile.position, closestCity.location)
civInfo.addNotification(
"Clearing a [$removedTerrainFeature] has created [$productionPointsToAdd] Production for [${closestCity.name}]",
locations, NotificationCategory.Production, NotificationIcon.Construction
)
}
}
fun healBy(amount: Int) {
health += amount *
if (hasUnique(UniqueType.HealingEffectsDoubled, checkCivInfoUniques = true)) 2
@ -878,6 +806,7 @@ class MapUnit : IsPartOfGameInfoSerialization {
}
}
fun canIntercept(attackedTile: Tile): Boolean {
if (!canIntercept()) return false
if (currentTile.aerialDistanceTo(attackedTile) > baseUnit.interceptRange) return false
@ -899,27 +828,6 @@ class MapUnit : IsPartOfGameInfoSerialization {
return getMatchingUniques(UniqueType.ChanceInterceptAirAttacks).sumOf { it.params[0].toInt() }
}
fun isTransportTypeOf(mapUnit: MapUnit): Boolean {
// Currently, only missiles and airplanes can be carried
if (!mapUnit.baseUnit.movesLikeAirUnits()) return false
return getMatchingUniques(UniqueType.CarryAirUnits).any { mapUnit.matchesFilter(it.params[1]) }
}
private fun carryCapacity(unit: MapUnit): Int {
return (getMatchingUniques(UniqueType.CarryAirUnits)
+ getMatchingUniques(UniqueType.CarryExtraAirUnits))
.filter { unit.matchesFilter(it.params[1]) }
.sumOf { it.params[0].toInt() }
}
fun canTransport(unit: MapUnit): Boolean {
if (owner != unit.owner) return false
if (!isTransportTypeOf(unit)) return false
if (unit.getMatchingUniques(UniqueType.CannotBeCarriedBy).any { matchesFilter(it.params[0]) }) return false
if (currentTile.airUnits.count { it.isTransported } >= carryCapacity(unit)) return false
return true
}
fun interceptDamagePercentBonus(): Int {
return getMatchingUniques(UniqueType.DamageWhenIntercepting)
.sumOf { it.params[0].toInt() }
@ -946,6 +854,28 @@ class MapUnit : IsPartOfGameInfoSerialization {
}
fun isTransportTypeOf(mapUnit: MapUnit): Boolean {
// Currently, only missiles and airplanes can be carried
if (!mapUnit.baseUnit.movesLikeAirUnits()) return false
return getMatchingUniques(UniqueType.CarryAirUnits).any { mapUnit.matchesFilter(it.params[1]) }
}
private fun carryCapacity(unit: MapUnit): Int {
return (getMatchingUniques(UniqueType.CarryAirUnits)
+ getMatchingUniques(UniqueType.CarryExtraAirUnits))
.filter { unit.matchesFilter(it.params[1]) }
.sumOf { it.params[0].toInt() }
}
fun canTransport(unit: MapUnit): Boolean {
if (owner != unit.owner) return false
if (!isTransportTypeOf(unit)) return false
if (unit.getMatchingUniques(UniqueType.CannotBeCarriedBy).any { matchesFilter(it.params[0]) }) return false
if (currentTile.airUnits.count { it.isTransported } >= carryCapacity(unit)) return false
return true
}
/** Implements [UniqueParameterType.MapUnitFilter][com.unciv.models.ruleset.unique.UniqueParameterType.MapUnitFilter] */
fun matchesFilter(filter: String): Boolean {
return filter.filterAndLogic { matchesFilter(it) } // multiple types at once - AND logic. Looks like:"{Military} {Land}"

View File

@ -1,8 +1,11 @@
package com.unciv.logic.map.mapunit
import com.unciv.Constants
import com.unciv.UncivGame
import com.unciv.logic.civilization.LocationAction
import com.unciv.logic.civilization.NotificationCategory
import com.unciv.logic.civilization.NotificationIcon
import com.unciv.logic.map.tile.RoadStatus
import com.unciv.models.ruleset.unique.UniqueType
class UnitTurnManager(val unit: MapUnit) {
@ -12,7 +15,7 @@ class UnitTurnManager(val unit: MapUnit) {
if (unit.currentMovement > 0
&& unit.getTile().improvementInProgress != null
&& unit.canBuildImprovement(unit.getTile().getTileImprovementInProgress()!!)
) unit.workOnImprovement()
) workOnImprovement()
if (unit.currentMovement == unit.getMaxMovement().toFloat() && unit.isFortified() && unit.turnsFortified < 2) {
unit.turnsFortified++
}
@ -166,4 +169,71 @@ class UnitTurnManager(val unit: MapUnit) {
unit.attacksSinceTurnStart.clear()
}
private fun workOnImprovement() {
val tile = unit.getTile()
if (tile.isMarkedForCreatesOneImprovement()) return
tile.turnsToImprovement -= 1
if (tile.turnsToImprovement != 0) return
if (unit.civInfo.isCurrentPlayer())
UncivGame.Current.settings.addCompletedTutorialTask("Construct an improvement")
when {
tile.improvementInProgress!!.startsWith(Constants.remove) -> {
val removedFeatureName = tile.improvementInProgress!!.removePrefix(Constants.remove)
val tileImprovement = tile.getTileImprovement()
if (tileImprovement != null
&& tile.terrainFeatures.any {
tileImprovement.terrainsCanBeBuiltOn.contains(it) && it == removedFeatureName
}
&& !tileImprovement.terrainsCanBeBuiltOn.contains(tile.baseTerrain)
) {
// We removed a terrain (e.g. Forest) and the improvement (e.g. Lumber mill) requires it!
tile.changeImprovement(null)
if (tile.resource != null) unit.civInfo.cache.updateCivResources() // unlikely, but maybe a mod makes a resource improvement dependent on a terrain feature
}
if (RoadStatus.values().any { tile.improvementInProgress == it.removeAction }) {
tile.removeRoad()
} else {
val removedFeatureObject = tile.ruleset.terrains[removedFeatureName]
if (removedFeatureObject != null && removedFeatureObject.hasUnique(UniqueType.ProductionBonusWhenRemoved)) {
tryProvideProductionToClosestCity(removedFeatureName)
}
tile.removeTerrainFeature(removedFeatureName)
}
}
tile.improvementInProgress == RoadStatus.Road.name -> tile.addRoad(RoadStatus.Road, unit.civInfo)
tile.improvementInProgress == RoadStatus.Railroad.name -> tile.addRoad(RoadStatus.Railroad, unit.civInfo)
tile.improvementInProgress == Constants.repair -> tile.setRepaired()
else -> {
val improvement = unit.civInfo.gameInfo.ruleSet.tileImprovements[tile.improvementInProgress]!!
improvement.handleImprovementCompletion(unit)
tile.changeImprovement(tile.improvementInProgress)
}
}
tile.improvementInProgress = null
tile.getCity()?.updateCitizens = true
}
private fun tryProvideProductionToClosestCity(removedTerrainFeature: String) {
val tile = unit.getTile()
val closestCity = unit.civInfo.cities.minByOrNull { it.getCenterTile().aerialDistanceTo(tile) }
@Suppress("FoldInitializerAndIfToElvis")
if (closestCity == null) return
val distance = closestCity.getCenterTile().aerialDistanceTo(tile)
var productionPointsToAdd = if (distance == 1) 20 else 20 - (distance - 2) * 5
if (tile.owningCity == null || tile.owningCity!!.civInfo != unit.civInfo) productionPointsToAdd =
productionPointsToAdd * 2 / 3
if (productionPointsToAdd > 0) {
closestCity.cityConstructions.addProductionPoints(productionPointsToAdd)
val locations = LocationAction(tile.position, closestCity.location)
unit.civInfo.addNotification(
"Clearing a [$removedTerrainFeature] has created [$productionPointsToAdd] Production for [${closestCity.name}]",
locations, NotificationCategory.Production, NotificationIcon.Construction
)
}
}
}

View File

@ -43,9 +43,6 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
var promotions = HashSet<String>()
var obsoleteTech: String? = null
var upgradesTo: String? = null
val specialUpgradesTo: String? by lazy {
getMatchingUniques(UniqueType.RuinsUpgrade).map { it.params[0] }.firstOrNull()
}
var replaces: String? = null
var uniqueTo: String? = null
var attackSound: String? = null

View File

@ -4,6 +4,7 @@ import com.unciv.logic.map.mapunit.MapUnit
import com.unciv.models.Counter
import com.unciv.models.UnitAction
import com.unciv.models.UnitActionType
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.tr
object UnitActionsUpgrade{
@ -22,13 +23,13 @@ object UnitActionsUpgrade{
isFree: Boolean,
isSpecial: Boolean
): UnitAction? {
if (unit.baseUnit().upgradesTo == null && unit.baseUnit().specialUpgradesTo == null) return null // can't upgrade to anything
val specialUpgradesTo = unit.baseUnit().getMatchingUniques(UniqueType.RuinsUpgrade).map { it.params[0] }.firstOrNull()
if (unit.baseUnit().upgradesTo == null && specialUpgradesTo == null) return null // can't upgrade to anything
val unitTile = unit.getTile()
val civInfo = unit.civInfo
if (!isFree && unitTile.getOwner() != civInfo) return null
val upgradesTo = unit.baseUnit().upgradesTo
val specialUpgradesTo = unit.baseUnit().specialUpgradesTo
val upgradedUnit = when {
isSpecial && specialUpgradesTo != null -> civInfo.getEquivalentUnit(specialUpgradesTo)
(isFree || isSpecial) && upgradesTo != null -> civInfo.getEquivalentUnit(upgradesTo) // Only get DIRECT upgrade