Barbarians capture civilians and take gold from cities (#5410)

* ransom cities

* capture civilians

* fix bug
This commit is contained in:
SimonCeder 2021-10-06 16:12:13 +02:00 committed by GitHub
parent c00ce49c86
commit b41d234db6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 7 deletions

View File

@ -544,6 +544,7 @@ An enemy [unit] has attacked [cityName] =
An enemy [unit] has attacked our [ourUnit] =
Enemy city [cityName] has attacked our [ourUnit] =
An enemy [unit] has captured [cityName] =
An enemy [unit] has raided [cityName] =
An enemy [unit] has captured our [ourUnit] =
An enemy [unit] has destroyed our [ourUnit] =
Your [ourUnit] has destroyed an enemy [unit] =
@ -599,6 +600,7 @@ We have received [goldAmount] Gold for discovering [naturalWonder] =
Your relationship with [cityStateName] is about to degrade =
Your relationship with [cityStateName] degraded =
A new barbarian encampment has spawned! =
Barbarians raided [cityName] and stole [amount] Gold from your treasury! =
Received [goldAmount] Gold for capturing [cityName] =
Our proposed trade is no longer relevant! =
[defender] could not withdraw from a [attacker] - blocked. =

View File

@ -14,10 +14,24 @@ class BarbarianAutomation(val civInfo: CivilizationInfo) {
}
private fun automateUnit(unit: MapUnit) {
if (unit.currentTile.improvement == Constants.barbarianEncampment) automateUnitOnEncampment(unit)
if (unit.isCivilian()) automateCapturedCivilian(unit)
else if (unit.currentTile.improvement == Constants.barbarianEncampment) automateUnitOnEncampment(unit)
else automateCombatUnit(unit)
}
private fun automateCapturedCivilian(unit: MapUnit) {
// 1 - Stay on current encampment
if (unit.currentTile.improvement == Constants.barbarianEncampment) return
val campTiles = unit.civInfo.gameInfo.barbarians.camps.map { unit.civInfo.gameInfo.tileMap[it.key] }
.sortedBy { unit.currentTile.aerialDistanceTo(it) }
val bestCamp = campTiles.firstOrNull { it.civilianUnit == null && unit.movement.canReach(it)}
if (bestCamp != null)
unit.movement.headTowards(bestCamp) // 2 - Head towards an encampment
else
UnitAutomation.wander(unit) // 3 - Can't find a reachable encampment, wander aimlessly
}
private fun automateUnitOnEncampment(unit: MapUnit) {
// 1 - trying to upgrade
if (UnitAutomation.tryUpgradeUnit(unit)) return

View File

@ -82,8 +82,17 @@ object Battle {
// This needs to come BEFORE the move-to-tile, because if we haven't conquered it we can't move there =)
if (defender.isDefeated() && defender is CityCombatant && attacker is MapUnitCombatant
&& attacker.isMelee() && !attacker.unit.hasUnique("Unable to capture cities"))
conquerCity(defender.city, attacker)
&& attacker.isMelee() && !attacker.unit.hasUnique("Unable to capture cities")) {
// Barbarians can't capture cities
if (attacker.unit.civInfo.isBarbarian()) {
defender.takeDamage(-1) // Back to 2 HP
val ransom = min(200, defender.city.civInfo.gold)
defender.city.civInfo.addGold(-ransom)
defender.city.civInfo.addNotification("Barbarians raided [${defender.city.name}] and stole [$ransom] Gold from your treasury!", defender.city.location, NotificationIcon.War)
attacker.unit.destroy() // Remove the barbarian
} else
conquerCity(defender.city, attacker)
}
// Exploring units surviving an attack should "wake up"
if (!defender.isDefeated() && defender is MapUnitCombatant && defender.unit.isExploring())
@ -270,6 +279,8 @@ object Battle {
NotificationIcon.War to " was destroyed while attacking"
!defender.isDefeated() ->
NotificationIcon.War to " has attacked"
defender.isCity() && attacker.isMelee() && attacker.getCivInfo().isBarbarian() ->
NotificationIcon.War to " has raided"
defender.isCity() && attacker.isMelee() ->
NotificationIcon.War to " has captured"
else ->
@ -468,12 +479,12 @@ object Battle {
val capturedUnitTile = capturedUnit.getTile()
when {
// Uncapturable units are destroyed (units captured by barbarians also - for now)
defender.unit.hasUnique("Uncapturable") || attacker.getCivInfo().isBarbarian() -> {
// Uncapturable units are destroyed
defender.unit.hasUnique("Uncapturable") -> {
capturedUnit.destroy()
}
// Captured settlers are converted to workers.
capturedUnit.name == Constants.settler -> {
// Captured settlers are converted to workers unless captured by barbarians (so they can be returned later).
capturedUnit.name == Constants.settler && !attacker.getCivInfo().isBarbarian() -> {
capturedUnit.destroy()
// This is so that future checks which check if a unit has been captured are caught give the right answer
// For example, in postBattleMoveToAttackedTile