mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-20 19:56:51 +01:00
Better main menu map
This commit is contained in:
parent
5bec368452
commit
291237a2eb
|
|
@ -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()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user