mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 15:27:50 +07:00
Quests fixes and additions (#5301)
* enable all quests * implement more quests * weighting for quests * global quests * fixes * fixes * Update template.properties * general string * reviews
This commit is contained in:
@ -22,12 +22,12 @@
|
||||
{
|
||||
"name": "Acquire Great Person",
|
||||
"description": "Great People can change the course of a Civilization! You will be rewarded for acquiring a new [greatPerson]."
|
||||
},/*
|
||||
},
|
||||
{
|
||||
"name": "Conquer City State",
|
||||
"description": "You will be rewarded for conquering the city state of [cityState]!",
|
||||
"description": "It's time to erase the City State of [cityState] from the map. You will be greatly rewarded for conquering them!",
|
||||
"influence": 80
|
||||
},*/
|
||||
},
|
||||
{
|
||||
"name": "Find Player",
|
||||
"description": "You have yet to discover where [civName] set up their cities. You will be rewarded for finding their territories.",
|
||||
@ -36,18 +36,17 @@
|
||||
{
|
||||
"name": "Find Natural Wonder",
|
||||
"description": "Send your best explorers on a quest to discover Natural Wonders. Nobody knows the location of [naturalWonder] yet."
|
||||
}
|
||||
},
|
||||
/* G&K */
|
||||
/*
|
||||
{
|
||||
"name": "Give Gold",
|
||||
"description": "We are suffering great poverty, and unless we receive a sum of [250] Gold, it's only a matter of time before we collapse.",
|
||||
"description": "We are suffering great poverty after being robbed by [civName], and unless we receive a sum of Gold, it's only a matter of time before we collapse.",
|
||||
"influence": 20,
|
||||
"duration": 30
|
||||
},
|
||||
{
|
||||
"name": "Pledge to Protect",
|
||||
"description": "Our peoples deserve to be protected by the likes of you. By signing a Protection Pedging, you'll confirm the bond that ties us.",
|
||||
"description": "We need your protection to stop the aggressions of [civName]. By signing a Pledge of Protection, you'll confirm the bond that ties us.",
|
||||
"influence": 20,
|
||||
"duration": 30
|
||||
},
|
||||
@ -66,7 +65,7 @@
|
||||
"minimumCivs": 3
|
||||
},
|
||||
{
|
||||
"name": "Contest Techs",
|
||||
"name": "Contest Technologies",
|
||||
"description": "The civilization with the largest number of new Technologies researched will gain a reward.",
|
||||
"type": "Global",
|
||||
"duration": 30,
|
||||
@ -74,7 +73,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Invest",
|
||||
"description": "Our people are rejoycing thanks to a tourism boom. For a certain amount of time, any Gold donation will yeld double the Influence.",
|
||||
"description": "Our people are rejoicing thanks to a tourism boom. For a certain amount of time, any Gold donation will yield [50]% extra Influence.",
|
||||
"type": "Global",
|
||||
"influence": 0,
|
||||
"duration": 30,
|
||||
@ -82,19 +81,18 @@
|
||||
},
|
||||
{
|
||||
"name": "Bully City State",
|
||||
"description": ""
|
||||
"description": "We are tired of the pretensions of [cityState]. If someone were to put them in their place by Demanding Tribute from them, they would be rewarded.",
|
||||
"duration": 30
|
||||
},
|
||||
{
|
||||
"name": "Denounce Civilization",
|
||||
"description": "",
|
||||
"description": "We have been forced to pay tribute to [civName]! We need you to tell the world of their ill deeds.",
|
||||
"duration": 30
|
||||
},
|
||||
{
|
||||
"name": "Spread Religion",
|
||||
"description": ""
|
||||
},
|
||||
*/
|
||||
"description": "We have heard the tenets of [religionName] and are most curious. Will you send missionaries to teach us about your religion?"
|
||||
}
|
||||
/* BNW */
|
||||
/*
|
||||
{
|
||||
|
@ -134,6 +134,8 @@ Ally =
|
||||
|
||||
[questName] (+[influenceAmount] influence) =
|
||||
[remainingTurns] turns remaining =
|
||||
Current leader is [civInfo] with [amount] [stat] generated. =
|
||||
Current leader is [civInfo] with [amount] Technologies discovered. =
|
||||
|
||||
## Diplomatic modifiers
|
||||
|
||||
|
@ -127,6 +127,10 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
}
|
||||
for (unique in donorCiv.getMatchingUniques("Gifts of Gold to City-States generate []% more Influence"))
|
||||
influenceGained *= 1f + unique.params[0].toFloat() / 100f
|
||||
|
||||
// Bonus due to "Invest" quests
|
||||
influenceGained *= civInfo.questManager.getInvestmentMultiplier(donorCiv.civName)
|
||||
|
||||
influenceGained -= influenceGained % 5
|
||||
if (influenceGained < 5f) influenceGained = 5f
|
||||
return influenceGained.toInt()
|
||||
@ -137,6 +141,7 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
donorCiv.addGold(-giftAmount)
|
||||
civInfo.addGold(giftAmount)
|
||||
civInfo.getDiplomacyManager(donorCiv).addInfluence(influenceGainedByGift(donorCiv, giftAmount).toFloat())
|
||||
civInfo.questManager.receivedGoldGift(donorCiv)
|
||||
}
|
||||
|
||||
fun getProtectorCivs() : List<CivilizationInfo> {
|
||||
@ -507,6 +512,13 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
protector.popupAlerts.add(PopupAlert(AlertType.BulliedProtectedMinor,
|
||||
bully.civName + "@" + civInfo.civName)) // we need to pass both civs as argument, hence the horrible chimera
|
||||
}
|
||||
|
||||
// Set a diplomatic flag so we remember for future quests (and not to give them any)
|
||||
civInfo.getDiplomacyManager(bully).setFlag(DiplomacyFlags.Bullied, 20)
|
||||
|
||||
// Notify all city states that we were bullied (for quests)
|
||||
civInfo.gameInfo.getAliveCityStates()
|
||||
.forEach { it.questManager.cityStateBullied(civInfo, bully) }
|
||||
}
|
||||
|
||||
/** A city state was attacked. What are its protectors going to do about it??? Also checks for Wary */
|
||||
@ -531,6 +543,8 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
continue
|
||||
if (!cityState.knows(attacker)) // Must have met
|
||||
continue
|
||||
if (cityState.questManager.wantsDead(civInfo.civName)) // Must not want us dead
|
||||
continue
|
||||
|
||||
var probability: Int
|
||||
if (attacker.isMinorCivWarmonger()) {
|
||||
@ -601,6 +615,10 @@ class CityStateFunctions(val civInfo: CivilizationInfo) {
|
||||
protector.addNotification("[${attacker.civName}] has destroyed [${civInfo.civName}], whom you had pledged to protect!", attacker.civName,
|
||||
NotificationIcon.Death, civInfo.civName)
|
||||
}
|
||||
|
||||
// Notify all city states that we were killed (for quest completion)
|
||||
civInfo.gameInfo.getAliveCityStates()
|
||||
.forEach { it.questManager.cityStateConquered(civInfo, attacker) }
|
||||
}
|
||||
|
||||
}
|
@ -162,6 +162,9 @@ class CivilizationInfo {
|
||||
// For Aggressor, Warmonger status
|
||||
private var numMinorCivsAttacked = 0
|
||||
|
||||
var totalCultureForContests = 0
|
||||
var totalFaithForContests = 0
|
||||
|
||||
constructor()
|
||||
|
||||
constructor(civName: String) {
|
||||
@ -209,6 +212,8 @@ class CivilizationInfo {
|
||||
toReturn.hasEverOwnedOriginalCapital = hasEverOwnedOriginalCapital
|
||||
toReturn.passableImpassables.addAll(passableImpassables)
|
||||
toReturn.numMinorCivsAttacked = numMinorCivsAttacked
|
||||
toReturn.totalCultureForContests = totalCultureForContests
|
||||
toReturn.totalFaithForContests = totalFaithForContests
|
||||
return toReturn
|
||||
}
|
||||
|
||||
@ -730,6 +735,7 @@ class CivilizationInfo {
|
||||
val nextTurnStats = statsForNextTurn
|
||||
|
||||
policies.endTurn(nextTurnStats.culture.toInt())
|
||||
totalCultureForContests += nextTurnStats.culture.toInt()
|
||||
|
||||
if (isCityState())
|
||||
questManager.endTurn()
|
||||
@ -754,6 +760,7 @@ class CivilizationInfo {
|
||||
tech.endTurn(nextTurnStats.science.toInt())
|
||||
|
||||
religionManager.endTurn(nextTurnStats.faith.toInt())
|
||||
totalFaithForContests += nextTurnStats.faith.toInt()
|
||||
|
||||
if (isMajorCiv()) greatPeople.addGreatPersonPoints(getGreatPersonPointsForNextTurn()) // City-states don't get great people!
|
||||
|
||||
@ -861,10 +868,12 @@ class CivilizationInfo {
|
||||
|
||||
fun addStat(stat: Stat, amount: Int) {
|
||||
when (stat) {
|
||||
Stat.Culture -> policies.addCulture(amount)
|
||||
Stat.Culture -> { policies.addCulture(amount)
|
||||
totalCultureForContests += amount }
|
||||
Stat.Science -> tech.addScience(amount)
|
||||
Stat.Gold -> addGold(amount)
|
||||
Stat.Faith -> religionManager.storedFaith += amount
|
||||
Stat.Faith -> { religionManager.storedFaith += amount
|
||||
totalFaithForContests += 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
|
||||
|
@ -4,7 +4,8 @@ import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.map.BFS
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.ruleset.Quest
|
||||
@ -13,7 +14,9 @@ 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.translations.fillPlaceholders
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.ui.utils.randomWeighted
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import kotlin.math.max
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -55,6 +58,18 @@ class QuestManager {
|
||||
/** Returns true if [civInfo] have active quests for [challenger] */
|
||||
fun haveQuestsFor(challenger: CivilizationInfo): Boolean = assignedQuests.any { it.assignee == challenger.civName }
|
||||
|
||||
/** Returns true if [civInfo] has asked anyone to conquer [target] */
|
||||
fun wantsDead(target: String): Boolean = assignedQuests.any { it.questName == QuestName.ConquerCityState.value && it.data1 == target }
|
||||
|
||||
/** Returns the influence multiplier for [donor] from a Investment quest that [civInfo] might have (assumes only one) */
|
||||
fun getInvestmentMultiplier(donor: String): Float {
|
||||
val investmentQuest = assignedQuests.firstOrNull { it.questName == QuestName.Invest.value && it.assignee == donor }
|
||||
return if (investmentQuest == null)
|
||||
1f
|
||||
else
|
||||
investmentQuest.data1.toPercent()
|
||||
}
|
||||
|
||||
fun clone(): QuestManager {
|
||||
val toReturn = QuestManager()
|
||||
toReturn.globalQuestCountdown = globalQuestCountdown
|
||||
@ -247,6 +262,8 @@ class QuestManager {
|
||||
|
||||
for (assignee in assignees) {
|
||||
|
||||
val playerReligion = civInfo.gameInfo.religions.values.firstOrNull { it.foundingCivName == assignee.civName && it.isMajorReligion() }
|
||||
|
||||
var data1 = ""
|
||||
var data2 = ""
|
||||
|
||||
@ -261,6 +278,17 @@ class QuestManager {
|
||||
QuestName.GreatPerson.value -> data1 = getGreatPersonForQuest(assignee)!!.name
|
||||
QuestName.FindPlayer.value -> data1 = getCivilizationToFindForQuest(assignee)!!.civName
|
||||
QuestName.FindNaturalWonder.value -> data1 = getNaturalWonderToFindForQuest(assignee)!!
|
||||
QuestName.ConquerCityState.value -> data1 = getCityStateTarget(assignee)!!.civName
|
||||
QuestName.BullyCityState.value -> data1 = getCityStateTarget(assignee)!!.civName
|
||||
QuestName.PledgeToProtect.value -> data1 = getMostRecentBully()!!
|
||||
QuestName.GiveGold.value -> data1 = getMostRecentBully()!!
|
||||
QuestName.DenounceCiv.value -> data1 = getMostRecentBully()!!
|
||||
QuestName.SpreadReligion.value -> { data1 = playerReligion!!.getReligionDisplayName() // For display
|
||||
data2 = playerReligion.name } // To check completion
|
||||
QuestName.ContestCulture.value -> data1 = assignee.totalCultureForContests.toString()
|
||||
QuestName.ContestFaith.value -> data1 = assignee.totalFaithForContests.toString()
|
||||
QuestName.ContestTech.value -> data1 = assignee.tech.getNumberOfTechsResearched().toString()
|
||||
QuestName.Invest.value -> data1 = quest.description.getPlaceholderParameters().first()
|
||||
}
|
||||
|
||||
val newQuest = AssignedQuest(
|
||||
@ -294,22 +322,33 @@ class QuestManager {
|
||||
return false
|
||||
if (assignedQuests.any { it.assignee == challenger.civName && it.questName == quest.name })
|
||||
return false
|
||||
if (quest.isIndividual() && civInfo.getDiplomacyManager(challenger).hasFlag(DiplomacyFlags.Bullied))
|
||||
return false
|
||||
|
||||
val mostRecentBully = getMostRecentBully()
|
||||
val playerReligion = civInfo.gameInfo.religions.values.firstOrNull() { it.foundingCivName == challenger.civName && it.isMajorReligion() }?.name
|
||||
|
||||
return when (quest.name) {
|
||||
QuestName.ClearBarbarianCamp.value -> getBarbarianEncampmentForQuest() != null
|
||||
QuestName.Route.value -> {
|
||||
if (challenger.cities.none() || !civInfo.hasEverBeenFriendWith(challenger)
|
||||
|| civInfo.isCapitalConnectedToCity(challenger.getCapital())) return false
|
||||
|
||||
val bfs = BFS(civInfo.getCapital().getCenterTile()) { it.isLand && !it.isImpassible() }
|
||||
bfs.stepUntilDestination(challenger.getCapital().getCenterTile())
|
||||
bfs.hasReachedTile(challenger.getCapital().getCenterTile())
|
||||
}
|
||||
QuestName.ConnectResource.value -> civInfo.hasEverBeenFriendWith(challenger) && getResourceForQuest(challenger) != null
|
||||
QuestName.ConstructWonder.value -> civInfo.hasEverBeenFriendWith(challenger) && getWonderToBuildForQuest(challenger) != null
|
||||
QuestName.GreatPerson.value -> civInfo.hasEverBeenFriendWith(challenger) && getGreatPersonForQuest(challenger) != null
|
||||
QuestName.FindPlayer.value -> civInfo.hasEverBeenFriendWith(challenger) && getCivilizationToFindForQuest(challenger) != null
|
||||
QuestName.FindNaturalWonder.value -> civInfo.hasEverBeenFriendWith(challenger) && getNaturalWonderToFindForQuest(challenger) != null
|
||||
QuestName.Route.value -> !challenger.cities.none()
|
||||
&& !civInfo.isCapitalConnectedToCity(challenger.getCapital())
|
||||
// Need to have a city within 7 tiles on the same continent
|
||||
&& challenger.cities.any { it.getCenterTile().aerialDistanceTo(civInfo.getCapital().getCenterTile()) <= 7
|
||||
&& it.getCenterTile().getContinent() == civInfo.getCapital().getCenterTile().getContinent() }
|
||||
QuestName.ConnectResource.value -> getResourceForQuest(challenger) != null
|
||||
QuestName.ConstructWonder.value -> getWonderToBuildForQuest(challenger) != null
|
||||
QuestName.GreatPerson.value -> getGreatPersonForQuest(challenger) != null
|
||||
QuestName.FindPlayer.value -> getCivilizationToFindForQuest(challenger) != null
|
||||
QuestName.FindNaturalWonder.value -> getNaturalWonderToFindForQuest(challenger) != null
|
||||
QuestName.PledgeToProtect.value -> mostRecentBully != null && challenger !in civInfo.getProtectorCivs()
|
||||
QuestName.GiveGold.value -> mostRecentBully != null
|
||||
QuestName.DenounceCiv.value -> mostRecentBully != null && challenger.knows(mostRecentBully)
|
||||
&& !challenger.getDiplomacyManager(mostRecentBully).hasFlag(DiplomacyFlags.Denunciation)
|
||||
&& challenger.getDiplomacyManager(mostRecentBully).diplomaticStatus != DiplomaticStatus.War
|
||||
&& !( challenger.playerType == PlayerType.Human && civInfo.gameInfo.getCivilization(mostRecentBully).playerType == PlayerType.Human)
|
||||
QuestName.SpreadReligion.value -> playerReligion != null && civInfo.getCapital().religion.getMajorityReligion()?.name != playerReligion
|
||||
QuestName.ConquerCityState.value -> getCityStateTarget(challenger) != null && civInfo.cityStatePersonality != CityStatePersonality.Friendly
|
||||
QuestName.BullyCityState.value -> getCityStateTarget(challenger) != null
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
@ -324,6 +363,9 @@ class QuestManager {
|
||||
QuestName.GreatPerson.value -> assignee.getCivGreatPeople().any { it.baseUnit.getReplacedUnit(civInfo.gameInfo.ruleSet).name == assignedQuest.data1 }
|
||||
QuestName.FindPlayer.value -> assignee.hasMetCivTerritory(civInfo.gameInfo.getCivilization(assignedQuest.data1))
|
||||
QuestName.FindNaturalWonder.value -> assignee.naturalWonders.contains(assignedQuest.data1)
|
||||
QuestName.PledgeToProtect.value -> assignee in civInfo.getProtectorCivs()
|
||||
QuestName.DenounceCiv.value -> assignee.getDiplomacyManager(assignedQuest.data1).hasFlag(DiplomacyFlags.Denunciation)
|
||||
QuestName.SpreadReligion.value -> civInfo.getCapital().religion.getMajorityReligion() == civInfo.gameInfo.religions[assignedQuest.data2]
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@ -335,6 +377,9 @@ class QuestManager {
|
||||
QuestName.ClearBarbarianCamp.value -> civInfo.gameInfo.tileMap[assignedQuest.data1.toInt(), assignedQuest.data2.toInt()].improvement != Constants.barbarianEncampment
|
||||
QuestName.ConstructWonder.value -> civInfo.gameInfo.getCities().any { it.civInfo != assignee && it.cityConstructions.isBuilt(assignedQuest.data1) }
|
||||
QuestName.FindPlayer.value -> civInfo.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
||||
QuestName.ConquerCityState.value -> civInfo.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
||||
QuestName.BullyCityState.value -> civInfo.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
||||
QuestName.DenounceCiv.value -> civInfo.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@ -358,14 +403,29 @@ class QuestManager {
|
||||
|
||||
/** Returns the score for the [assignedQuest] */
|
||||
private fun getScoreForQuest(assignedQuest: AssignedQuest): Int {
|
||||
@Suppress("UNUSED_VARIABLE") // This is a work in progress
|
||||
val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee)
|
||||
return when (assignedQuest.questName) {
|
||||
// Waiting for contest quests
|
||||
QuestName.ContestCulture.value -> assignee.totalCultureForContests - assignedQuest.data1.toInt()
|
||||
QuestName.ContestFaith.value -> assignee.totalFaithForContests - assignedQuest.data1.toInt()
|
||||
QuestName.ContestTech.value -> assignee.tech.getNumberOfTechsResearched() - assignedQuest.data1.toInt()
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a string with the leading civ and their score for [questName] */
|
||||
fun getLeaderStringForQuest(questName: String): String {
|
||||
val leadingQuest = assignedQuests.filter { it.questName == questName }.maxByOrNull { getScoreForQuest(it) }
|
||||
if (leadingQuest == null)
|
||||
return ""
|
||||
|
||||
return when (questName){
|
||||
QuestName.ContestCulture.value -> "Current leader is ${leadingQuest.assignee} with ${getScoreForQuest(leadingQuest)} [Culture] generated."
|
||||
QuestName.ContestFaith.value -> "Current leader is ${leadingQuest.assignee} with ${getScoreForQuest(leadingQuest)} [Faith] generated."
|
||||
QuestName.ContestTech.value -> "Current leader is ${leadingQuest.assignee} with ${getScoreForQuest(leadingQuest)} Technologies discovered."
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets notified a barbarian camp in [location] has been cleared by [civInfo].
|
||||
* Since [QuestName.ClearBarbarianCamp] is a global quest, it could have been assigned to
|
||||
@ -383,6 +443,59 @@ class QuestManager {
|
||||
assignedQuests.removeAll(matchingQuests)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets notified the city state [cityState] was just conquered by [attacker].
|
||||
*/
|
||||
fun cityStateConquered(cityState: CivilizationInfo, attacker: CivilizationInfo) {
|
||||
val matchingQuests = assignedQuests.asSequence()
|
||||
.filter { it.questName == QuestName.ConquerCityState.value }
|
||||
.filter { it.data1 == cityState.civName && it.assignee == attacker.civName}
|
||||
|
||||
for (quest in matchingQuests)
|
||||
giveReward(quest)
|
||||
|
||||
assignedQuests.removeAll(matchingQuests)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets notified the city state [cityState] was just bullied by [bully].
|
||||
*/
|
||||
fun cityStateBullied(cityState: CivilizationInfo, bully: CivilizationInfo) {
|
||||
val matchingQuests = assignedQuests.asSequence()
|
||||
.filter { it.questName == QuestName.BullyCityState.value }
|
||||
.filter { it.data1 == cityState.civName && it.assignee == bully.civName}
|
||||
|
||||
for (quest in matchingQuests)
|
||||
giveReward(quest)
|
||||
|
||||
assignedQuests.removeAll(matchingQuests)
|
||||
|
||||
// What idiots haha oh wait that's us
|
||||
if (civInfo == cityState) {
|
||||
// Revoke most quest types from the bully
|
||||
val revokedQuests = assignedQuests.asSequence()
|
||||
.filter { it.isIndividual() || it.questName == QuestName.Invest.value }
|
||||
assignedQuests.removeAll(revokedQuests)
|
||||
if (revokedQuests.count() > 0)
|
||||
bully.addNotification("[${civInfo.civName}] cancelled the quests they had given you because you demanded tribute from them.",
|
||||
DiplomacyAction(civInfo.civName), civInfo.civName, "OtherIcons/Quest")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets notified when given gold by [donorCiv].
|
||||
*/
|
||||
fun receivedGoldGift(donorCiv: CivilizationInfo) {
|
||||
val matchingQuests = assignedQuests.asSequence()
|
||||
.filter { it.questName == QuestName.GiveGold.value }
|
||||
.filter { it.assignee == donorCiv.civName}
|
||||
|
||||
for (quest in matchingQuests)
|
||||
giveReward(quest)
|
||||
|
||||
assignedQuests.removeAll(matchingQuests)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the weight of the [questName], depends on city state trait and personality
|
||||
*/
|
||||
@ -440,6 +553,56 @@ class QuestManager {
|
||||
if (trait == CityStateType.Militaristic)
|
||||
weight *= 3f
|
||||
}
|
||||
QuestName.GiveGold.value -> {
|
||||
when (trait) {
|
||||
CityStateType.Militaristic -> weight *= 2f
|
||||
CityStateType.Mercantile -> weight *= 3.5f
|
||||
else -> weight *= 3f
|
||||
}
|
||||
}
|
||||
QuestName.PledgeToProtect.value -> {
|
||||
when (trait) {
|
||||
CityStateType.Militaristic -> weight *= 2f
|
||||
CityStateType.Cultured -> weight *= 3.5f
|
||||
else -> weight *= 3f
|
||||
}
|
||||
}
|
||||
QuestName.BullyCityState.value -> {
|
||||
when (personality) {
|
||||
CityStatePersonality.Hostile -> weight *= 2f
|
||||
CityStatePersonality.Irrational -> weight *= 1.5f
|
||||
CityStatePersonality.Friendly -> weight *= .3f
|
||||
}
|
||||
}
|
||||
QuestName.DenounceCiv.value -> {
|
||||
when (trait) {
|
||||
CityStateType.Religious -> weight *= 2.5f
|
||||
CityStateType.Maritime -> weight *= 2f
|
||||
else -> weight *= 1.5f
|
||||
}
|
||||
}
|
||||
QuestName.SpreadReligion.value -> {
|
||||
if (trait == CityStateType.Religious)
|
||||
weight *= 3f
|
||||
}
|
||||
QuestName.ContestCulture.value -> {
|
||||
if (trait == CityStateType.Cultured)
|
||||
weight *= 2f
|
||||
}
|
||||
QuestName.ContestFaith.value -> {
|
||||
when (trait) {
|
||||
CityStateType.Religious -> weight *= 2f
|
||||
else -> weight *= .5f
|
||||
}
|
||||
}
|
||||
QuestName.ContestTech.value -> {
|
||||
if (trait == CityStateType.Religious)
|
||||
weight *= .5f
|
||||
}
|
||||
QuestName.Invest.value -> {
|
||||
if (trait == CityStateType.Mercantile)
|
||||
weight *= 1.5f
|
||||
}
|
||||
}
|
||||
return weight
|
||||
}
|
||||
@ -486,11 +649,21 @@ class QuestManager {
|
||||
}
|
||||
|
||||
private fun getWonderToBuildForQuest(challenger: CivilizationInfo): Building? {
|
||||
val startingEra = civInfo.gameInfo.ruleSet.eras[civInfo.gameInfo.gameParameters.startingEra]!!
|
||||
val wonders = civInfo.gameInfo.ruleSet.buildings.values
|
||||
.filter { building ->
|
||||
building.isWonder &&
|
||||
(building.requiredTech == null || challenger.tech.isResearched(building.requiredTech!!)) &&
|
||||
civInfo.gameInfo.getCities().none { it.cityConstructions.isBuilt(building.name) }
|
||||
// Buildable wonder
|
||||
building.isWonder
|
||||
&& (building.requiredTech == null || challenger.tech.isResearched(building.requiredTech!!))
|
||||
&& civInfo.gameInfo.getCities().none { it.cityConstructions.isBuilt(building.name) }
|
||||
// Can't be disabled
|
||||
&& building.name !in startingEra.startingObsoleteWonders
|
||||
&& (civInfo.gameInfo.gameParameters.religionEnabled || !building.hasUnique("Hidden when religion is disabled"))
|
||||
// Can't be more than 25% built anywhere
|
||||
&& civInfo.gameInfo.getCities().none {
|
||||
it.cityConstructions.getWorkDone(building.name) * 3 > it.cityConstructions.getRemainingWork(building.name) }
|
||||
// Can't be a unique wonder
|
||||
&& building.uniqueTo == null
|
||||
}
|
||||
|
||||
if (wonders.isNotEmpty())
|
||||
@ -545,6 +718,29 @@ class QuestManager {
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a city-state [CivilizationInfo] that [civInfo] wants to target for hostile quests
|
||||
*/
|
||||
private fun getCityStateTarget(challenger: CivilizationInfo): CivilizationInfo? {
|
||||
val closestProximity = civInfo.gameInfo.getAliveCityStates()
|
||||
.mapNotNull { civInfo.proximity[it.civName] }.filter { it != Proximity.None }.minByOrNull { it.ordinal }
|
||||
|
||||
if (closestProximity == null || closestProximity == Proximity.Distant) // None close enough
|
||||
return null
|
||||
|
||||
val validTargets = civInfo.getKnownCivs().filter { it.isCityState() && challenger.knows(it)
|
||||
&& civInfo.proximity[it.civName] == closestProximity }
|
||||
|
||||
return validTargets.randomOrNull()
|
||||
}
|
||||
|
||||
/** Returns a [CivilizationInfo] of the civ that most recently bullied [civInfo].
|
||||
* Note: forgets after 20 turns has passed! */
|
||||
private fun getMostRecentBully(): String? {
|
||||
val bullies = civInfo.diplomacy.values.filter { it.hasFlag(DiplomacyFlags.Bullied)}
|
||||
return bullies.maxByOrNull { it.getFlag(DiplomacyFlags.Bullied) }?.otherCivName
|
||||
}
|
||||
//endregion
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ enum class DiplomacyFlags {
|
||||
RememberSidedWithProtectedMinor,
|
||||
Denunciation,
|
||||
WaryOf,
|
||||
Bullied,
|
||||
}
|
||||
|
||||
enum class DiplomaticModifiers {
|
||||
|
@ -11,6 +11,15 @@ enum class QuestName(val value: String) {
|
||||
ConquerCityState("Conquer City State"),
|
||||
FindPlayer("Find Player"),
|
||||
FindNaturalWonder("Find Natural Wonder"),
|
||||
GiveGold("Give Gold"),
|
||||
PledgeToProtect("Pledge to Protect"),
|
||||
ContestCulture("Contest Culture"),
|
||||
ContestFaith("Contest Faith"),
|
||||
ContestTech("Contest Technologies"),
|
||||
Invest("Invest"),
|
||||
BullyCityState("Bully City State"),
|
||||
DenounceCiv("Denounce Civilization"),
|
||||
SpreadReligion("Spread Religion"),
|
||||
None("")
|
||||
}
|
||||
|
||||
|
@ -541,7 +541,10 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
|
||||
|
||||
val quest: Quest = viewingCiv.gameInfo.ruleSet.quests[assignedQuest.questName]!!
|
||||
val remainingTurns: Int = assignedQuest.getRemainingTurns()
|
||||
val title = "[${quest.name}] (+[${quest.influence.toInt()}] influence)"
|
||||
val title = if (quest.influence > 0)
|
||||
"[${quest.name}] (+[${quest.influence.toInt()}] influence)"
|
||||
else
|
||||
quest.name
|
||||
val description = assignedQuest.getDescription()
|
||||
|
||||
questTable.add(title.toLabel(fontSize = 24)).row()
|
||||
@ -549,6 +552,11 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() {
|
||||
.width(stage.width / 2).row()
|
||||
if (quest.duration > 0)
|
||||
questTable.add("[${remainingTurns}] turns remaining".toLabel()).row()
|
||||
if (quest.isGlobal()) {
|
||||
val leaderString = viewingCiv.gameInfo.getCivilization(assignedQuest.assigner).questManager.getLeaderStringForQuest(assignedQuest.questName)
|
||||
if (leaderString != "")
|
||||
questTable.add(leaderString.toLabel()).row()
|
||||
}
|
||||
|
||||
questTable.onClick {
|
||||
assignedQuest.onClickAction()
|
||||
|
Reference in New Issue
Block a user