|
|
@ -30,9 +30,9 @@ import com.unciv.models.ruleset.unique.UniqueType
|
|
|
|
import com.unciv.models.ruleset.unit.BaseUnit
|
|
|
|
import com.unciv.models.ruleset.unit.BaseUnit
|
|
|
|
import com.unciv.models.translations.fillPlaceholders
|
|
|
|
import com.unciv.models.translations.fillPlaceholders
|
|
|
|
import com.unciv.models.translations.getPlaceholderParameters
|
|
|
|
import com.unciv.models.translations.getPlaceholderParameters
|
|
|
|
|
|
|
|
import com.unciv.models.translations.tr
|
|
|
|
import com.unciv.ui.components.extensions.randomWeighted
|
|
|
|
import com.unciv.ui.components.extensions.randomWeighted
|
|
|
|
import com.unciv.ui.components.extensions.toPercent
|
|
|
|
import com.unciv.ui.components.extensions.toPercent
|
|
|
|
import kotlin.math.max
|
|
|
|
|
|
|
|
import kotlin.random.Random
|
|
|
|
import kotlin.random.Random
|
|
|
|
|
|
|
|
|
|
|
|
class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
@ -58,10 +58,13 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
|
|
|
|
|
|
|
|
/** Civilization object holding and dispatching quests */
|
|
|
|
/** Civilization object holding and dispatching quests */
|
|
|
|
@Transient
|
|
|
|
@Transient
|
|
|
|
lateinit var civInfo: Civilization
|
|
|
|
private lateinit var civ: Civilization
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Readability helper to access the Ruleset through [civ] */
|
|
|
|
|
|
|
|
private val ruleset get() = civ.gameInfo.ruleset
|
|
|
|
|
|
|
|
|
|
|
|
/** List of active quests, both global and individual ones*/
|
|
|
|
/** List of active quests, both global and individual ones*/
|
|
|
|
var assignedQuests: ArrayList<AssignedQuest> = ArrayList()
|
|
|
|
private var assignedQuests: ArrayList<AssignedQuest> = ArrayList()
|
|
|
|
|
|
|
|
|
|
|
|
/** Number of turns left before starting new global quest */
|
|
|
|
/** Number of turns left before starting new global quest */
|
|
|
|
private var globalQuestCountdown: Int = UNSET
|
|
|
|
private var globalQuestCountdown: Int = UNSET
|
|
|
@ -76,15 +79,24 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
/** For this attacker, number of units killed by each civ */
|
|
|
|
/** For this attacker, number of units killed by each civ */
|
|
|
|
private var unitsKilledFromCiv: HashMap<String, HashMap<String, Int>> = HashMap()
|
|
|
|
private var unitsKilledFromCiv: HashMap<String, HashMap<String, Int>> = HashMap()
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns true if [civInfo] have active quests for [challenger] */
|
|
|
|
/** Returns true if [civ] have active quests for [challenger] */
|
|
|
|
fun haveQuestsFor(challenger: Civilization): Boolean = assignedQuests.any { it.assignee == challenger.civName }
|
|
|
|
fun haveQuestsFor(challenger: Civilization): Boolean = getAssignedQuestsFor(challenger.civName).any()
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns true if [civInfo] has asked anyone to conquer [target] */
|
|
|
|
/** Access all assigned Quests for [civName] */
|
|
|
|
fun wantsDead(target: String): Boolean = assignedQuests.any { it.questName == QuestName.ConquerCityState.value && it.data1 == target }
|
|
|
|
fun getAssignedQuestsFor(civName: String) =
|
|
|
|
|
|
|
|
assignedQuests.asSequence().filter { it.assignee == civName }
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns the influence multiplier for [donor] from a Investment quest that [civInfo] might have (assumes only one) */
|
|
|
|
/** Access all assigned Quests of "type" [questName] */
|
|
|
|
|
|
|
|
// Note if we decide to cache an index of these (such as `assignedQuests.groupBy { it.questNameInstance }`), this accessor would simplify the transition
|
|
|
|
|
|
|
|
private fun getAssignedQuestsOfName(questName: QuestName) =
|
|
|
|
|
|
|
|
assignedQuests.asSequence().filter { it.questNameInstance == questName }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns true if [civ] has asked anyone to conquer [target] */
|
|
|
|
|
|
|
|
fun wantsDead(target: String): Boolean = getAssignedQuestsOfName(QuestName.ConquerCityState).any { it.data1 == target }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns the influence multiplier for [donor] from a Investment quest that [civ] might have (assumes only one) */
|
|
|
|
fun getInvestmentMultiplier(donor: String): Float {
|
|
|
|
fun getInvestmentMultiplier(donor: String): Float {
|
|
|
|
val investmentQuest = assignedQuests.firstOrNull { it.questName == QuestName.Invest.value && it.assignee == donor }
|
|
|
|
val investmentQuest = getAssignedQuestsOfName(QuestName.Invest).firstOrNull { it.assignee == donor }
|
|
|
|
?: return 1f
|
|
|
|
?: return 1f
|
|
|
|
return investmentQuest.data1.toPercent()
|
|
|
|
return investmentQuest.data1.toPercent()
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -96,31 +108,30 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
toReturn.assignedQuests.addAll(assignedQuests)
|
|
|
|
toReturn.assignedQuests.addAll(assignedQuests)
|
|
|
|
toReturn.unitsToKillForCiv.putAll(unitsToKillForCiv)
|
|
|
|
toReturn.unitsToKillForCiv.putAll(unitsToKillForCiv)
|
|
|
|
for ((attacker, unitsKilled) in unitsKilledFromCiv) {
|
|
|
|
for ((attacker, unitsKilled) in unitsKilledFromCiv) {
|
|
|
|
toReturn.unitsKilledFromCiv[attacker] = HashMap()
|
|
|
|
toReturn.unitsKilledFromCiv[attacker] = HashMap(unitsKilled)
|
|
|
|
toReturn.unitsKilledFromCiv[attacker]!!.putAll(unitsKilled)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return toReturn
|
|
|
|
return toReturn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun setTransients(civInfo: Civilization) {
|
|
|
|
fun setTransients(civ: Civilization) {
|
|
|
|
this.civInfo = civInfo
|
|
|
|
this.civ = civ
|
|
|
|
for (quest in assignedQuests)
|
|
|
|
for (quest in assignedQuests)
|
|
|
|
quest.gameInfo = civInfo.gameInfo
|
|
|
|
quest.setTransients(civ.gameInfo)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun endTurn() {
|
|
|
|
fun endTurn() {
|
|
|
|
|
|
|
|
|
|
|
|
if (civInfo.isDefeated()) {
|
|
|
|
if (civ.isDefeated()) {
|
|
|
|
assignedQuests.clear()
|
|
|
|
assignedQuests.clear()
|
|
|
|
individualQuestCountdown.clear()
|
|
|
|
individualQuestCountdown.clear()
|
|
|
|
globalQuestCountdown = UNSET
|
|
|
|
globalQuestCountdown = UNSET
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (civInfo.cities.none()) return // don't assign quests until we have a city
|
|
|
|
if (civ.cities.isEmpty()) return // don't assign quests until we have a city
|
|
|
|
|
|
|
|
|
|
|
|
seedGlobalQuestCountdown()
|
|
|
|
seedGlobalQuestCountdown()
|
|
|
|
seedIndividualQuestsCountdown()
|
|
|
|
seedIndividualQuestsCountdowns()
|
|
|
|
|
|
|
|
|
|
|
|
decrementQuestCountdowns()
|
|
|
|
decrementQuestCountdowns()
|
|
|
|
|
|
|
|
|
|
|
@ -144,26 +155,26 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun seedGlobalQuestCountdown() {
|
|
|
|
private fun seedGlobalQuestCountdown() {
|
|
|
|
if (civInfo.gameInfo.turns < GLOBAL_QUEST_FIRST_POSSIBLE_TURN)
|
|
|
|
if (civ.gameInfo.turns < GLOBAL_QUEST_FIRST_POSSIBLE_TURN)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
if (globalQuestCountdown != UNSET)
|
|
|
|
if (globalQuestCountdown != UNSET)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
val countdown =
|
|
|
|
val countdown =
|
|
|
|
if (civInfo.gameInfo.turns == GLOBAL_QUEST_FIRST_POSSIBLE_TURN)
|
|
|
|
if (civ.gameInfo.turns == GLOBAL_QUEST_FIRST_POSSIBLE_TURN)
|
|
|
|
Random.nextInt(GLOBAL_QUEST_FIRST_POSSIBLE_TURN_RAND)
|
|
|
|
Random.nextInt(GLOBAL_QUEST_FIRST_POSSIBLE_TURN_RAND)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
GLOBAL_QUEST_MIN_TURNS_BETWEEN + Random.nextInt(GLOBAL_QUEST_RAND_TURNS_BETWEEN)
|
|
|
|
GLOBAL_QUEST_MIN_TURNS_BETWEEN + Random.nextInt(GLOBAL_QUEST_RAND_TURNS_BETWEEN)
|
|
|
|
|
|
|
|
|
|
|
|
globalQuestCountdown = (countdown * civInfo.gameInfo.speed.modifier).toInt()
|
|
|
|
globalQuestCountdown = (countdown * civ.gameInfo.speed.modifier).toInt()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun seedIndividualQuestsCountdown() {
|
|
|
|
private fun seedIndividualQuestsCountdowns() {
|
|
|
|
if (civInfo.gameInfo.turns < INDIVIDUAL_QUEST_FIRST_POSSIBLE_TURN)
|
|
|
|
if (civ.gameInfo.turns < INDIVIDUAL_QUEST_FIRST_POSSIBLE_TURN)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
val majorCivs = civInfo.gameInfo.getAliveMajorCivs()
|
|
|
|
val majorCivs = civ.gameInfo.getAliveMajorCivs()
|
|
|
|
for (majorCiv in majorCivs)
|
|
|
|
for (majorCiv in majorCivs)
|
|
|
|
if (!individualQuestCountdown.containsKey(majorCiv.civName) || individualQuestCountdown[majorCiv.civName] == UNSET)
|
|
|
|
if (!individualQuestCountdown.containsKey(majorCiv.civName) || individualQuestCountdown[majorCiv.civName] == UNSET)
|
|
|
|
seedIndividualQuestsCountdown(majorCiv)
|
|
|
|
seedIndividualQuestsCountdown(majorCiv)
|
|
|
@ -171,36 +182,34 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
|
|
|
|
|
|
|
|
private fun seedIndividualQuestsCountdown(challenger: Civilization) {
|
|
|
|
private fun seedIndividualQuestsCountdown(challenger: Civilization) {
|
|
|
|
val countdown: Int =
|
|
|
|
val countdown: Int =
|
|
|
|
if (civInfo.gameInfo.turns == INDIVIDUAL_QUEST_FIRST_POSSIBLE_TURN)
|
|
|
|
if (civ.gameInfo.turns == INDIVIDUAL_QUEST_FIRST_POSSIBLE_TURN)
|
|
|
|
Random.nextInt(INDIVIDUAL_QUEST_FIRST_POSSIBLE_TURN_RAND)
|
|
|
|
Random.nextInt(INDIVIDUAL_QUEST_FIRST_POSSIBLE_TURN_RAND)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
INDIVIDUAL_QUEST_MIN_TURNS_BETWEEN + Random.nextInt(
|
|
|
|
INDIVIDUAL_QUEST_MIN_TURNS_BETWEEN + Random.nextInt(
|
|
|
|
INDIVIDUAL_QUEST_RAND_TURNS_BETWEEN
|
|
|
|
INDIVIDUAL_QUEST_RAND_TURNS_BETWEEN
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
individualQuestCountdown[challenger.civName] = (countdown * civInfo.gameInfo.speed.modifier).toInt()
|
|
|
|
individualQuestCountdown[challenger.civName] = (countdown * civ.gameInfo.speed.modifier).toInt()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Readabilty helper - No asSequence(): call frequency * data size is small
|
|
|
|
|
|
|
|
private fun getQuests(predicate: (Quest) -> Boolean) = ruleset.quests.values.filter(predicate)
|
|
|
|
|
|
|
|
|
|
|
|
private fun tryStartNewGlobalQuest() {
|
|
|
|
private fun tryStartNewGlobalQuest() {
|
|
|
|
if (globalQuestCountdown != 0)
|
|
|
|
if (globalQuestCountdown != 0)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
if (assignedQuests.count { it.isGlobal() } >= GLOBAL_QUEST_MAX_ACTIVE)
|
|
|
|
if (assignedQuests.count { it.isGlobal() } >= GLOBAL_QUEST_MAX_ACTIVE)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
val globalQuests = civInfo.gameInfo.ruleset.quests.values.filter { it.isGlobal() }
|
|
|
|
val majorCivs = civ.getKnownCivs().filter { it.isMajorCiv() && !it.isAtWarWith(civ) } // A Sequence - fine because the count below can be different for each Quest
|
|
|
|
val majorCivs = civInfo.getKnownCivs().filter { it.isMajorCiv() && !it.isAtWarWith(civInfo) }
|
|
|
|
fun Quest.isAssignable() = majorCivs.count { civ -> isQuestValid(this, civ) } >= minimumCivs
|
|
|
|
|
|
|
|
val assignableQuests = getQuests {
|
|
|
|
val assignableQuests = ArrayList<Quest>()
|
|
|
|
it.isGlobal() && it.isAssignable()
|
|
|
|
for (quest in globalQuests) {
|
|
|
|
|
|
|
|
val numberValidMajorCivs = majorCivs.count { civ -> isQuestValid(quest, civ) }
|
|
|
|
|
|
|
|
if (numberValidMajorCivs >= quest.minimumCivs)
|
|
|
|
|
|
|
|
assignableQuests.add(quest)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
val weights = assignableQuests.map { getQuestWeight(it.name) }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (assignableQuests.isNotEmpty()) {
|
|
|
|
if (assignableQuests.isNotEmpty()) {
|
|
|
|
val quest = assignableQuests.randomWeighted(weights)
|
|
|
|
val quest = assignableQuests.randomWeighted { getQuestWeight(it.name) }
|
|
|
|
val assignees = civInfo.gameInfo.getAliveMajorCivs().filter { !it.isAtWarWith(civInfo) && isQuestValid(quest, it) }
|
|
|
|
val assignees = civ.gameInfo.getAliveMajorCivs().filter { !it.isAtWarWith(civ) && isQuestValid(quest, it) }
|
|
|
|
|
|
|
|
|
|
|
|
assignNewQuest(quest, assignees)
|
|
|
|
assignNewQuest(quest, assignees)
|
|
|
|
globalQuestCountdown = UNSET
|
|
|
|
globalQuestCountdown = UNSET
|
|
|
@ -209,19 +218,18 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
|
|
|
|
|
|
|
|
private fun tryStartNewIndividualQuests() {
|
|
|
|
private fun tryStartNewIndividualQuests() {
|
|
|
|
for ((challengerName, countdown) in individualQuestCountdown) {
|
|
|
|
for ((challengerName, countdown) in individualQuestCountdown) {
|
|
|
|
val challenger = civInfo.gameInfo.getCivilization(challengerName)
|
|
|
|
val challenger = civ.gameInfo.getCivilization(challengerName)
|
|
|
|
|
|
|
|
|
|
|
|
if (countdown != 0)
|
|
|
|
if (countdown != 0)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
if (assignedQuests.count { it.assignee == challenger.civName && it.isIndividual() } >= INDIVIDUAL_QUEST_MAX_ACTIVE)
|
|
|
|
if (getAssignedQuestsFor(challenger.civName).count { it.isIndividual() } >= INDIVIDUAL_QUEST_MAX_ACTIVE)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
val assignableQuests = civInfo.gameInfo.ruleset.quests.values.filter { it.isIndividual() && isQuestValid(it, challenger) }
|
|
|
|
val assignableQuests = getQuests { it.isIndividual() && isQuestValid(it, challenger) }
|
|
|
|
val weights = assignableQuests.map { getQuestWeight(it.name) }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (assignableQuests.isNotEmpty()) {
|
|
|
|
if (assignableQuests.isNotEmpty()) {
|
|
|
|
val quest = assignableQuests.randomWeighted(weights)
|
|
|
|
val quest = assignableQuests.randomWeighted { getQuestWeight(it.name) }
|
|
|
|
val assignees = arrayListOf(challenger)
|
|
|
|
val assignees = arrayListOf(challenger)
|
|
|
|
|
|
|
|
|
|
|
|
assignNewQuest(quest, assignees)
|
|
|
|
assignNewQuest(quest, assignees)
|
|
|
@ -230,46 +238,42 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun tryBarbarianInvasion() {
|
|
|
|
private fun tryBarbarianInvasion() {
|
|
|
|
if ((civInfo.getTurnsTillCallForBarbHelp() == null || civInfo.getTurnsTillCallForBarbHelp() == 0)
|
|
|
|
if ((civ.getTurnsTillCallForBarbHelp() == null || civ.getTurnsTillCallForBarbHelp() == 0)
|
|
|
|
&& civInfo.cityStateFunctions.getNumThreateningBarbarians() >= 2) {
|
|
|
|
&& civ.cityStateFunctions.getNumThreateningBarbarians() >= 2) {
|
|
|
|
|
|
|
|
|
|
|
|
for (otherCiv in civInfo.getKnownCivs().filter {
|
|
|
|
for (otherCiv in civ.getKnownCivs().filter {
|
|
|
|
it.isMajorCiv()
|
|
|
|
it.isMajorCiv()
|
|
|
|
&& it.isAlive()
|
|
|
|
&& it.isAlive()
|
|
|
|
&& !it.isAtWarWith(civInfo)
|
|
|
|
&& !it.isAtWarWith(civ)
|
|
|
|
&& it.getProximity(civInfo) <= Proximity.Far
|
|
|
|
&& it.getProximity(civ) <= Proximity.Far
|
|
|
|
}) {
|
|
|
|
}) {
|
|
|
|
otherCiv.addNotification("[${civInfo.civName}] is being invaded by Barbarians! Destroy Barbarians near their territory to earn Influence.",
|
|
|
|
otherCiv.addNotification(
|
|
|
|
civInfo.getCapital()!!.location,
|
|
|
|
"[${civ.civName}] is being invaded by Barbarians! Destroy Barbarians near their territory to earn Influence.",
|
|
|
|
NotificationCategory.Diplomacy, civInfo.civName,
|
|
|
|
civ.getCapital()!!.location,
|
|
|
|
|
|
|
|
NotificationCategory.Diplomacy, civ.civName,
|
|
|
|
NotificationIcon.War
|
|
|
|
NotificationIcon.War
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
civInfo.addFlag(CivFlags.TurnsTillCallForBarbHelp.name, 30)
|
|
|
|
civ.addFlag(CivFlags.TurnsTillCallForBarbHelp.name, 30)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun handleGlobalQuests() {
|
|
|
|
private fun handleGlobalQuests() {
|
|
|
|
// Remove any participants that are no longer valid because of being dead or at war with the CS
|
|
|
|
// Remove any participants that are no longer valid because of being dead or at war with the CS
|
|
|
|
assignedQuests.removeAll { it.isGlobal() &&
|
|
|
|
assignedQuests.removeAll { it.isGlobal() &&
|
|
|
|
!canAssignAQuestTo(civInfo.gameInfo.getCivilization(it.assignee)) }
|
|
|
|
!canAssignAQuestTo(civ.gameInfo.getCivilization(it.assignee)) }
|
|
|
|
val globalQuestsExpired = assignedQuests.filter { it.isGlobal() && it.isExpired() }.map { it.questName }.distinct()
|
|
|
|
val globalQuestsExpired = assignedQuests.filter { it.isGlobal() && it.isExpired() }.map { it.questNameInstance }.distinct()
|
|
|
|
for (globalQuestName in globalQuestsExpired)
|
|
|
|
for (globalQuestName in globalQuestsExpired)
|
|
|
|
handleGlobalQuest(globalQuestName)
|
|
|
|
handleGlobalQuest(globalQuestName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun handleGlobalQuest(questName: String) {
|
|
|
|
private fun handleGlobalQuest(questName: QuestName) {
|
|
|
|
val quests = assignedQuests.filter { it.questName == questName }
|
|
|
|
val winnersAndLosers = WinnersAndLosers(questName)
|
|
|
|
if (quests.isEmpty())
|
|
|
|
winnersAndLosers.winners.forEach { giveReward(it) }
|
|
|
|
return
|
|
|
|
winnersAndLosers.losers.forEach { notifyExpired(it, winnersAndLosers.winners) }
|
|
|
|
|
|
|
|
|
|
|
|
val topScore = quests.maxOf { getScoreForQuest(it) }
|
|
|
|
assignedQuests.removeAll(winnersAndLosers.winners)
|
|
|
|
val winners = quests.filter { getScoreForQuest(it) == topScore }
|
|
|
|
assignedQuests.removeAll(winnersAndLosers.losers)
|
|
|
|
winners.forEach { giveReward(it) }
|
|
|
|
|
|
|
|
for (loser in quests.filterNot { it in winners })
|
|
|
|
|
|
|
|
notifyExpired(loser, winners)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assignedQuests.removeAll(quests)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun handleIndividualQuests() {
|
|
|
|
private fun handleIndividualQuests() {
|
|
|
@ -279,7 +283,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
/** If quest is complete, it gives the influence reward to the player.
|
|
|
|
/** If quest is complete, it gives the influence reward to the player.
|
|
|
|
* Returns true if the quest can be removed (is either complete, obsolete or expired) */
|
|
|
|
* Returns true if the quest can be removed (is either complete, obsolete or expired) */
|
|
|
|
private fun handleIndividualQuest(assignedQuest: AssignedQuest): Boolean {
|
|
|
|
private fun handleIndividualQuest(assignedQuest: AssignedQuest): Boolean {
|
|
|
|
val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
val assignee = civ.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
|
|
|
|
|
|
|
|
// One of the civs is defeated, or they started a war: remove quest
|
|
|
|
// One of the civs is defeated, or they started a war: remove quest
|
|
|
|
if (!canAssignAQuestTo(assignee))
|
|
|
|
if (!canAssignAQuestTo(assignee))
|
|
|
@ -305,195 +309,269 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
|
|
|
|
|
|
|
|
private fun assignNewQuest(quest: Quest, assignees: Iterable<Civilization>) {
|
|
|
|
private fun assignNewQuest(quest: Quest, assignees: Iterable<Civilization>) {
|
|
|
|
|
|
|
|
|
|
|
|
val turn = civInfo.gameInfo.turns
|
|
|
|
val turn = civ.gameInfo.turns
|
|
|
|
|
|
|
|
|
|
|
|
for (assignee in assignees) {
|
|
|
|
for (assignee in assignees) {
|
|
|
|
|
|
|
|
|
|
|
|
val playerReligion = civInfo.gameInfo.religions.values.firstOrNull { it.foundingCivName == assignee.civName && it.isMajorReligion() }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var data1 = ""
|
|
|
|
var data1 = ""
|
|
|
|
var data2 = ""
|
|
|
|
var data2 = ""
|
|
|
|
var notificationActions: List<NotificationAction> = listOf(DiplomacyAction(civInfo.civName))
|
|
|
|
var notificationActions: List<NotificationAction> = listOf(DiplomacyAction(civ.civName))
|
|
|
|
|
|
|
|
|
|
|
|
when (quest.name) {
|
|
|
|
when (quest.questNameInstance) {
|
|
|
|
QuestName.ClearBarbarianCamp.value -> {
|
|
|
|
QuestName.ClearBarbarianCamp -> {
|
|
|
|
val camp = getBarbarianEncampmentForQuest()!!
|
|
|
|
val camp = getBarbarianEncampmentForQuest()!!
|
|
|
|
data1 = camp.position.x.toInt().toString()
|
|
|
|
data1 = camp.position.x.toInt().toString()
|
|
|
|
data2 = camp.position.y.toInt().toString()
|
|
|
|
data2 = camp.position.y.toInt().toString()
|
|
|
|
notificationActions = listOf(LocationAction(camp.position), notificationActions.first())
|
|
|
|
notificationActions = listOf(LocationAction(camp.position), notificationActions.first())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QuestName.ConnectResource.value -> data1 = getResourceForQuest(assignee)!!.name
|
|
|
|
QuestName.ConnectResource -> data1 = getResourceForQuest(assignee)!!.name
|
|
|
|
QuestName.ConstructWonder.value -> data1 = getWonderToBuildForQuest(assignee)!!.name
|
|
|
|
QuestName.ConstructWonder -> data1 = getWonderToBuildForQuest(assignee)!!.name
|
|
|
|
QuestName.GreatPerson.value -> data1 = getGreatPersonForQuest(assignee)!!.name
|
|
|
|
QuestName.GreatPerson -> data1 = getGreatPersonForQuest(assignee)!!.name
|
|
|
|
QuestName.FindPlayer.value -> data1 = getCivilizationToFindForQuest(assignee)!!.civName
|
|
|
|
QuestName.FindPlayer -> data1 = getCivilizationToFindForQuest(assignee)!!.civName
|
|
|
|
QuestName.FindNaturalWonder.value -> data1 = getNaturalWonderToFindForQuest(assignee)!!
|
|
|
|
QuestName.FindNaturalWonder -> data1 = getNaturalWonderToFindForQuest(assignee)!!
|
|
|
|
QuestName.ConquerCityState.value -> data1 = getCityStateTarget(assignee)!!.civName
|
|
|
|
QuestName.ConquerCityState -> data1 = getCityStateTarget(assignee)!!.civName
|
|
|
|
QuestName.BullyCityState.value -> data1 = getCityStateTarget(assignee)!!.civName
|
|
|
|
QuestName.BullyCityState -> data1 = getCityStateTarget(assignee)!!.civName
|
|
|
|
QuestName.PledgeToProtect.value -> data1 = getMostRecentBully()!!
|
|
|
|
QuestName.PledgeToProtect -> data1 = getMostRecentBully()!!
|
|
|
|
QuestName.GiveGold.value -> data1 = getMostRecentBully()!!
|
|
|
|
QuestName.GiveGold -> data1 = getMostRecentBully()!!
|
|
|
|
QuestName.DenounceCiv.value -> data1 = getMostRecentBully()!!
|
|
|
|
QuestName.DenounceCiv -> data1 = getMostRecentBully()!!
|
|
|
|
QuestName.SpreadReligion.value -> {
|
|
|
|
QuestName.SpreadReligion -> {
|
|
|
|
data1 = playerReligion!!.getReligionDisplayName() // For display
|
|
|
|
val playerReligion = civ.gameInfo.religions.values
|
|
|
|
|
|
|
|
.first { it.foundingCivName == assignee.civName && it.isMajorReligion() } // isQuestValid must have ensured this won't throw
|
|
|
|
|
|
|
|
data1 = playerReligion.getReligionDisplayName() // For display
|
|
|
|
data2 = playerReligion.name // To check completion
|
|
|
|
data2 = playerReligion.name // To check completion
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QuestName.ContestCulture.value -> data1 = assignee.totalCultureForContests.toString()
|
|
|
|
QuestName.ContestCulture -> data1 = assignee.totalCultureForContests.toString()
|
|
|
|
QuestName.ContestFaith.value -> data1 = assignee.totalFaithForContests.toString()
|
|
|
|
QuestName.ContestFaith -> data1 = assignee.totalFaithForContests.toString()
|
|
|
|
QuestName.ContestTech.value -> data1 = assignee.tech.getNumberOfTechsResearched().toString()
|
|
|
|
QuestName.ContestTech -> data1 = assignee.tech.getNumberOfTechsResearched().toString()
|
|
|
|
QuestName.Invest.value -> data1 = quest.description.getPlaceholderParameters().first()
|
|
|
|
QuestName.Invest -> data1 = quest.description.getPlaceholderParameters().first()
|
|
|
|
|
|
|
|
else -> Unit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
val newQuest = AssignedQuest(
|
|
|
|
val newQuest = AssignedQuest(
|
|
|
|
questName = quest.name,
|
|
|
|
questName = quest.name,
|
|
|
|
assigner = civInfo.civName,
|
|
|
|
assigner = civ.civName,
|
|
|
|
assignee = assignee.civName,
|
|
|
|
assignee = assignee.civName,
|
|
|
|
assignedOnTurn = turn,
|
|
|
|
assignedOnTurn = turn,
|
|
|
|
data1 = data1,
|
|
|
|
data1 = data1,
|
|
|
|
data2 = data2
|
|
|
|
data2 = data2
|
|
|
|
)
|
|
|
|
)
|
|
|
|
newQuest.gameInfo = civInfo.gameInfo
|
|
|
|
newQuest.setTransients(civ.gameInfo, quest)
|
|
|
|
|
|
|
|
|
|
|
|
assignedQuests.add(newQuest)
|
|
|
|
assignedQuests.add(newQuest)
|
|
|
|
assignee.addNotification("[${civInfo.civName}] assigned you a new quest: [${quest.name}].",
|
|
|
|
|
|
|
|
notificationActions,
|
|
|
|
|
|
|
|
NotificationCategory.Diplomacy, civInfo.civName, "OtherIcons/Quest")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (quest.isIndividual())
|
|
|
|
if (quest.isIndividual())
|
|
|
|
individualQuestCountdown[assignee.civName] = UNSET
|
|
|
|
individualQuestCountdown[assignee.civName] = UNSET
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assignee.addNotification("[${civ.civName}] assigned you a new quest: [${quest.name}].",
|
|
|
|
|
|
|
|
notificationActions,
|
|
|
|
|
|
|
|
NotificationCategory.Diplomacy, civ.civName, "OtherIcons/Quest")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns true if [civInfo] can assign a quest to [challenger] */
|
|
|
|
/** Returns true if [civ] can assign a quest to [challenger] */
|
|
|
|
private fun canAssignAQuestTo(challenger: Civilization): Boolean {
|
|
|
|
private fun canAssignAQuestTo(challenger: Civilization): Boolean {
|
|
|
|
return !challenger.isDefeated() && challenger.isMajorCiv() &&
|
|
|
|
return !challenger.isDefeated() && challenger.isMajorCiv() &&
|
|
|
|
civInfo.knows(challenger) && !civInfo.isAtWarWith(challenger)
|
|
|
|
civ.knows(challenger) && !civ.isAtWarWith(challenger)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns true if the [quest] can be assigned to [challenger] */
|
|
|
|
/** Returns true if the [quest] can be assigned to [challenger] */
|
|
|
|
private fun isQuestValid(quest: Quest, challenger: Civilization): Boolean {
|
|
|
|
private fun isQuestValid(quest: Quest, challenger: Civilization): Boolean {
|
|
|
|
if (!canAssignAQuestTo(challenger))
|
|
|
|
if (!canAssignAQuestTo(challenger))
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
if (assignedQuests.any { it.assignee == challenger.civName && it.questName == quest.name })
|
|
|
|
if (getAssignedQuestsOfName(quest.questNameInstance).any { it.assignee == challenger.civName })
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
if (quest.isIndividual() && civInfo.getDiplomacyManager(challenger).hasFlag(DiplomacyFlags.Bullied))
|
|
|
|
if (quest.isIndividual() && civ.getDiplomacyManager(challenger).hasFlag(DiplomacyFlags.Bullied))
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
|
|
|
|
|
|
|
|
val mostRecentBully = getMostRecentBully()
|
|
|
|
return when (quest.questNameInstance) {
|
|
|
|
val playerReligion = civInfo.gameInfo.religions.values.firstOrNull { it.foundingCivName == challenger.civName && it.isMajorReligion() }?.name
|
|
|
|
QuestName.ClearBarbarianCamp -> getBarbarianEncampmentForQuest() != null
|
|
|
|
|
|
|
|
QuestName.Route -> isRouteQuestValid(challenger)
|
|
|
|
return when (quest.name) {
|
|
|
|
QuestName.ConnectResource -> getResourceForQuest(challenger) != null
|
|
|
|
QuestName.ClearBarbarianCamp.value -> getBarbarianEncampmentForQuest() != null
|
|
|
|
QuestName.ConstructWonder -> getWonderToBuildForQuest(challenger) != null
|
|
|
|
QuestName.Route.value -> !challenger.cities.none()
|
|
|
|
QuestName.GreatPerson -> getGreatPersonForQuest(challenger) != null
|
|
|
|
&& !challenger.isCapitalConnectedToCity(civInfo.getCapital()!!)
|
|
|
|
QuestName.FindPlayer -> getCivilizationToFindForQuest(challenger) != null
|
|
|
|
// Need to have a city within 7 tiles on the same continent
|
|
|
|
QuestName.FindNaturalWonder -> getNaturalWonderToFindForQuest(challenger) != null
|
|
|
|
&& challenger.cities.any { it.getCenterTile().aerialDistanceTo(civInfo.getCapital()!!.getCenterTile()) <= 7
|
|
|
|
QuestName.PledgeToProtect -> getMostRecentBully() != null && challenger !in civ.cityStateFunctions.getProtectorCivs()
|
|
|
|
&& it.getCenterTile().getContinent() == civInfo.getCapital()!!.getCenterTile().getContinent() }
|
|
|
|
QuestName.GiveGold -> getMostRecentBully() != null
|
|
|
|
QuestName.ConnectResource.value -> getResourceForQuest(challenger) != null
|
|
|
|
QuestName.DenounceCiv -> isDenounceCivQuestValid(challenger, getMostRecentBully())
|
|
|
|
QuestName.ConstructWonder.value -> getWonderToBuildForQuest(challenger) != null
|
|
|
|
QuestName.SpreadReligion -> {
|
|
|
|
QuestName.GreatPerson.value -> getGreatPersonForQuest(challenger) != null
|
|
|
|
val playerReligion = civ.gameInfo.religions.values.firstOrNull { it.foundingCivName == challenger.civName && it.isMajorReligion() }?.name
|
|
|
|
QuestName.FindPlayer.value -> getCivilizationToFindForQuest(challenger) != null
|
|
|
|
playerReligion != null && civ.getCapital()!!.religion.getMajorityReligion()?.name != playerReligion
|
|
|
|
QuestName.FindNaturalWonder.value -> getNaturalWonderToFindForQuest(challenger) != null
|
|
|
|
}
|
|
|
|
QuestName.PledgeToProtect.value -> mostRecentBully != null && challenger !in civInfo.cityStateFunctions.getProtectorCivs()
|
|
|
|
QuestName.ConquerCityState -> getCityStateTarget(challenger) != null && civ.cityStatePersonality != CityStatePersonality.Friendly
|
|
|
|
QuestName.GiveGold.value -> mostRecentBully != null
|
|
|
|
QuestName.BullyCityState -> getCityStateTarget(challenger) != null
|
|
|
|
QuestName.DenounceCiv.value -> mostRecentBully != null && challenger.knows(mostRecentBully)
|
|
|
|
QuestName.ContestFaith -> civ.gameInfo.isReligionEnabled()
|
|
|
|
&& !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
|
|
|
|
|
|
|
|
QuestName.ContestFaith.value -> civInfo.gameInfo.isReligionEnabled()
|
|
|
|
|
|
|
|
else -> true
|
|
|
|
else -> true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun isRouteQuestValid(challenger: Civilization): Boolean {
|
|
|
|
|
|
|
|
if (challenger.cities.isEmpty()) return false
|
|
|
|
|
|
|
|
if (challenger.isCapitalConnectedToCity(civ.getCapital()!!)) return false
|
|
|
|
|
|
|
|
val capital = civ.getCapital() ?: return false
|
|
|
|
|
|
|
|
val capitalTile = capital.getCenterTile()
|
|
|
|
|
|
|
|
return challenger.cities.any {
|
|
|
|
|
|
|
|
it.getCenterTile().getContinent() == capitalTile.getContinent() &&
|
|
|
|
|
|
|
|
it.getCenterTile().aerialDistanceTo(capitalTile) <= 7
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun isDenounceCivQuestValid(challenger: Civilization, mostRecentBully: String?): Boolean {
|
|
|
|
|
|
|
|
return mostRecentBully != null
|
|
|
|
|
|
|
|
&& challenger.knows(mostRecentBully)
|
|
|
|
|
|
|
|
&& !challenger.getDiplomacyManager(mostRecentBully).hasFlag(DiplomacyFlags.Denunciation)
|
|
|
|
|
|
|
|
&& challenger.getDiplomacyManager(mostRecentBully).diplomaticStatus != DiplomaticStatus.War
|
|
|
|
|
|
|
|
&& !( challenger.playerType == PlayerType.Human
|
|
|
|
|
|
|
|
&& civ.gameInfo.getCivilization(mostRecentBully).playerType == PlayerType.Human)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns true if the [assignedQuest] is successfully completed */
|
|
|
|
/** Returns true if the [assignedQuest] is successfully completed */
|
|
|
|
private fun isComplete(assignedQuest: AssignedQuest): Boolean {
|
|
|
|
private fun isComplete(assignedQuest: AssignedQuest): Boolean {
|
|
|
|
val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
val assignee = civ.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
return when (assignedQuest.questName) {
|
|
|
|
return when (assignedQuest.questNameInstance) {
|
|
|
|
QuestName.Route.value -> assignee.isCapitalConnectedToCity(civInfo.getCapital()!!)
|
|
|
|
QuestName.Route -> assignee.isCapitalConnectedToCity(civ.getCapital()!!)
|
|
|
|
QuestName.ConnectResource.value -> assignee.detailedCivResources.map { it.resource }.contains(civInfo.gameInfo.ruleset.tileResources[assignedQuest.data1])
|
|
|
|
QuestName.ConnectResource -> assignee.detailedCivResources.map { it.resource }.contains(ruleset.tileResources[assignedQuest.data1])
|
|
|
|
QuestName.ConstructWonder.value -> assignee.cities.any { it.cityConstructions.isBuilt(assignedQuest.data1) }
|
|
|
|
QuestName.ConstructWonder -> assignee.cities.any { it.cityConstructions.isBuilt(assignedQuest.data1) }
|
|
|
|
QuestName.GreatPerson.value -> assignee.units.getCivGreatPeople().any { it.baseUnit.getReplacedUnit(civInfo.gameInfo.ruleset).name == assignedQuest.data1 }
|
|
|
|
QuestName.GreatPerson -> assignee.units.getCivGreatPeople().any { it.baseUnit.getReplacedUnit(ruleset).name == assignedQuest.data1 }
|
|
|
|
QuestName.FindPlayer.value -> assignee.hasMetCivTerritory(civInfo.gameInfo.getCivilization(assignedQuest.data1))
|
|
|
|
QuestName.FindPlayer -> assignee.hasMetCivTerritory(civ.gameInfo.getCivilization(assignedQuest.data1))
|
|
|
|
QuestName.FindNaturalWonder.value -> assignee.naturalWonders.contains(assignedQuest.data1)
|
|
|
|
QuestName.FindNaturalWonder -> assignee.naturalWonders.contains(assignedQuest.data1)
|
|
|
|
QuestName.PledgeToProtect.value -> assignee in civInfo.cityStateFunctions.getProtectorCivs()
|
|
|
|
QuestName.PledgeToProtect -> assignee in civ.cityStateFunctions.getProtectorCivs()
|
|
|
|
QuestName.DenounceCiv.value -> assignee.getDiplomacyManager(assignedQuest.data1).hasFlag(DiplomacyFlags.Denunciation)
|
|
|
|
QuestName.DenounceCiv -> assignee.getDiplomacyManager(assignedQuest.data1).hasFlag(DiplomacyFlags.Denunciation)
|
|
|
|
QuestName.SpreadReligion.value -> civInfo.getCapital()!!.religion.getMajorityReligion() == civInfo.gameInfo.religions[assignedQuest.data2]
|
|
|
|
QuestName.SpreadReligion -> civ.getCapital()!!.religion.getMajorityReligion() == civ.gameInfo.religions[assignedQuest.data2]
|
|
|
|
else -> false
|
|
|
|
else -> false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns true if the [assignedQuest] request cannot be fulfilled anymore */
|
|
|
|
/** Returns true if the [assignedQuest] request cannot be fulfilled anymore */
|
|
|
|
private fun isObsolete(assignedQuest: AssignedQuest): Boolean {
|
|
|
|
private fun isObsolete(assignedQuest: AssignedQuest): Boolean {
|
|
|
|
val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
val assignee = civ.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
return when (assignedQuest.questName) {
|
|
|
|
return when (assignedQuest.questNameInstance) {
|
|
|
|
QuestName.ClearBarbarianCamp.value -> civInfo.gameInfo.tileMap[assignedQuest.data1.toInt(), assignedQuest.data2.toInt()].improvement != Constants.barbarianEncampment
|
|
|
|
QuestName.ClearBarbarianCamp -> civ.gameInfo.tileMap[assignedQuest.data1.toInt(), assignedQuest.data2.toInt()].improvement != Constants.barbarianEncampment
|
|
|
|
QuestName.ConstructWonder.value -> civInfo.gameInfo.getCities().any { it.civ != assignee && it.cityConstructions.isBuilt(assignedQuest.data1) }
|
|
|
|
QuestName.ConstructWonder -> civ.gameInfo.getCities().any { it.civ != assignee && it.cityConstructions.isBuilt(assignedQuest.data1) }
|
|
|
|
QuestName.FindPlayer.value -> civInfo.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
|
|
|
QuestName.FindPlayer -> civ.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
|
|
|
QuestName.ConquerCityState.value -> civInfo.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
|
|
|
QuestName.ConquerCityState -> civ.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
|
|
|
QuestName.BullyCityState.value -> civInfo.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
|
|
|
QuestName.BullyCityState -> civ.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
|
|
|
QuestName.DenounceCiv.value -> civInfo.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
|
|
|
QuestName.DenounceCiv -> civ.gameInfo.getCivilization(assignedQuest.data1).isDefeated()
|
|
|
|
else -> false
|
|
|
|
else -> false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Increments [assignedQuest.assignee][AssignedQuest.assignee] influence on [civInfo] and adds a [Notification] */
|
|
|
|
/** Increments [assignedQuest.assignee][AssignedQuest.assignee] influence on [civ] and adds a [Notification] */
|
|
|
|
private fun giveReward(assignedQuest: AssignedQuest) {
|
|
|
|
private fun giveReward(assignedQuest: AssignedQuest) {
|
|
|
|
val rewardInfluence = civInfo.gameInfo.ruleset.quests[assignedQuest.questName]!!.influence
|
|
|
|
val rewardInfluence = assignedQuest.getInfluence()
|
|
|
|
val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
val assignee = civ.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
|
|
|
|
|
|
|
|
civInfo.getDiplomacyManager(assignedQuest.assignee).addInfluence(rewardInfluence)
|
|
|
|
civ.getDiplomacyManager(assignedQuest.assignee).addInfluence(rewardInfluence)
|
|
|
|
if (rewardInfluence > 0)
|
|
|
|
if (rewardInfluence > 0)
|
|
|
|
assignee.addNotification(
|
|
|
|
assignee.addNotification(
|
|
|
|
"[${civInfo.civName}] rewarded you with [${rewardInfluence.toInt()}] influence for completing the [${assignedQuest.questName}] quest.",
|
|
|
|
"[${civ.civName}] rewarded you with [${rewardInfluence.toInt()}] influence for completing the [${assignedQuest.questName}] quest.",
|
|
|
|
civInfo.getCapital()!!.location, NotificationCategory.Diplomacy, civInfo.civName, "OtherIcons/Quest"
|
|
|
|
civ.getCapital()!!.location, NotificationCategory.Diplomacy, civ.civName, "OtherIcons/Quest"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// We may have received bonuses from city-state friend-ness or ally-ness
|
|
|
|
// We may have received bonuses from city-state friend-ness or ally-ness
|
|
|
|
for (city in civInfo.cities)
|
|
|
|
for (city in civ.cities)
|
|
|
|
city.cityStats.update()
|
|
|
|
city.cityStats.update()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Notifies the assignee of [assignedQuest] that the quest is now obsolete or expired.
|
|
|
|
/** Notifies the assignee of [assignedQuest] that the quest is now obsolete or expired.
|
|
|
|
* Optionally displays the [winners] of global quests. */
|
|
|
|
* Optionally displays the [winners] of global quests. */
|
|
|
|
private fun notifyExpired(assignedQuest: AssignedQuest, winners: List<AssignedQuest> = emptyList()) {
|
|
|
|
private fun notifyExpired(assignedQuest: AssignedQuest, winners: List<AssignedQuest> = emptyList()) {
|
|
|
|
val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
val assignee = civ.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
if (winners.isEmpty()) {
|
|
|
|
if (winners.isEmpty()) {
|
|
|
|
assignee.addNotification(
|
|
|
|
assignee.addNotification(
|
|
|
|
"[${civInfo.civName}] no longer needs your help with the [${assignedQuest.questName}] quest.",
|
|
|
|
"[${civ.civName}] no longer needs your help with the [${assignedQuest.questName}] quest.",
|
|
|
|
civInfo.getCapital()!!.location,
|
|
|
|
civ.getCapital()!!.location,
|
|
|
|
NotificationCategory.Diplomacy, civInfo.civName, "OtherIcons/Quest")
|
|
|
|
NotificationCategory.Diplomacy, civ.civName, "OtherIcons/Quest")
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
assignee.addNotification(
|
|
|
|
assignee.addNotification(
|
|
|
|
"The [${assignedQuest.questName}] quest for [${civInfo.civName}] has ended. It was won by [${winners.joinToString { "{${it.assignee}}" }}].",
|
|
|
|
"The [${assignedQuest.questName}] quest for [${civ.civName}] has ended. It was won by [${winners.joinToString { "{${it.assignee}}" }}].",
|
|
|
|
civInfo.getCapital()!!.location,
|
|
|
|
civ.getCapital()!!.location,
|
|
|
|
NotificationCategory.Diplomacy, civInfo.civName, "OtherIcons/Quest")
|
|
|
|
NotificationCategory.Diplomacy, civ.civName, "OtherIcons/Quest")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns the score for the [assignedQuest] */
|
|
|
|
/** Returns the score for the [assignedQuest] */
|
|
|
|
private fun getScoreForQuest(assignedQuest: AssignedQuest): Int {
|
|
|
|
private fun getScoreForQuest(assignedQuest: AssignedQuest): Int {
|
|
|
|
val assignee = civInfo.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
val assignee = civ.gameInfo.getCivilization(assignedQuest.assignee)
|
|
|
|
return when (assignedQuest.questName) {
|
|
|
|
|
|
|
|
QuestName.ContestCulture.value -> assignee.totalCultureForContests - assignedQuest.data1.toInt()
|
|
|
|
return when (assignedQuest.questNameInstance) {
|
|
|
|
QuestName.ContestFaith.value -> assignee.totalFaithForContests - assignedQuest.data1.toInt()
|
|
|
|
//quest total = civ total - the value at the time the quest started (which was stored in assignedQuest.data1)
|
|
|
|
QuestName.ContestTech.value -> assignee.tech.getNumberOfTechsResearched() - assignedQuest.data1.toInt()
|
|
|
|
QuestName.ContestCulture -> assignee.totalCultureForContests - assignedQuest.data1.toInt()
|
|
|
|
|
|
|
|
QuestName.ContestFaith -> assignee.totalFaithForContests - assignedQuest.data1.toInt()
|
|
|
|
|
|
|
|
QuestName.ContestTech -> assignee.tech.getNumberOfTechsResearched() - assignedQuest.data1.toInt()
|
|
|
|
else -> 0
|
|
|
|
else -> 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns a string with the leading civ and their score for [questName] */
|
|
|
|
/** Evaluate a contest-type quest:
|
|
|
|
fun getLeaderStringForQuest(questName: String): String {
|
|
|
|
*
|
|
|
|
val leadingQuest = assignedQuests.filter { it.questName == questName }.maxByOrNull { getScoreForQuest(it) }
|
|
|
|
* - Determines [winner(s)][winners] (as AssignedQuest instances, which name their assignee): Those whose score is the [maximum score][maxScore], possibly tied.
|
|
|
|
?: return ""
|
|
|
|
* and [losers]: all other [assignedQuests] matching parameter `questName`.
|
|
|
|
|
|
|
|
* - Called by the UI via [getScoreStringForGlobalQuest] before a Contest is resolved to display who currently leads,
|
|
|
|
|
|
|
|
* and by [handleGlobalQuest] to distribute rewards and notifications.
|
|
|
|
|
|
|
|
* @param questName filters [assignedQuests] by their [QuestName][AssignedQuest.questNameInstance]
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
inner class WinnersAndLosers(questName: QuestName) {
|
|
|
|
|
|
|
|
val winners = mutableListOf<AssignedQuest>()
|
|
|
|
|
|
|
|
val losers = mutableListOf<AssignedQuest>()
|
|
|
|
|
|
|
|
var maxScore: Int = -1
|
|
|
|
|
|
|
|
private set
|
|
|
|
|
|
|
|
|
|
|
|
return when (questName) {
|
|
|
|
init {
|
|
|
|
QuestName.ContestCulture.value -> "Current leader is [${leadingQuest.assignee}] with [${getScoreForQuest(leadingQuest)}] [Culture] generated."
|
|
|
|
require(ruleset.quests[questName.value]!!.isGlobal())
|
|
|
|
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."
|
|
|
|
for (quest in getAssignedQuestsOfName(questName)) {
|
|
|
|
else -> ""
|
|
|
|
val qScore = getScoreForQuest(quest)
|
|
|
|
|
|
|
|
when {
|
|
|
|
|
|
|
|
qScore <= 0 -> Unit // no civ is a winner if their score is 0
|
|
|
|
|
|
|
|
qScore < maxScore ->
|
|
|
|
|
|
|
|
losers.add(quest)
|
|
|
|
|
|
|
|
qScore == maxScore ->
|
|
|
|
|
|
|
|
winners.add(quest)
|
|
|
|
|
|
|
|
else -> { // qScore > maxScore
|
|
|
|
|
|
|
|
losers.addAll(winners)
|
|
|
|
|
|
|
|
winners.clear()
|
|
|
|
|
|
|
|
winners.add(quest)
|
|
|
|
|
|
|
|
maxScore = qScore
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns a string to show "competition" status:
|
|
|
|
|
|
|
|
* - Show leading civ(s) (more than one only if tied for first place) with best score.
|
|
|
|
|
|
|
|
* - The assignee civ of the given [inquiringAssignedQuest] is shown for comparison if it is not among the leaders.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* Assumes the result will be passed to [String.tr] - but parts are pretranslated to avoid nested brackets.
|
|
|
|
|
|
|
|
* Tied leaders are separated by ", " - translators cannot influence this, sorry.
|
|
|
|
|
|
|
|
* @param inquiringAssignedQuest Determines ["type"][AssignedQuest.questNameInstance] to find all competitors in [assignedQuests] and [viewing civ][AssignedQuest.assignee].
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
fun getScoreStringForGlobalQuest(inquiringAssignedQuest: AssignedQuest): String {
|
|
|
|
|
|
|
|
require(inquiringAssignedQuest.assigner == civ.civName)
|
|
|
|
|
|
|
|
require(inquiringAssignedQuest.isGlobal())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val scoreDescriptor = when (inquiringAssignedQuest.questNameInstance) {
|
|
|
|
|
|
|
|
QuestName.ContestCulture -> "Culture"
|
|
|
|
|
|
|
|
QuestName.ContestFaith -> "Faith"
|
|
|
|
|
|
|
|
QuestName.ContestTech -> "Technologies"
|
|
|
|
|
|
|
|
else -> return "" //This handles global quests which aren't a competition, like invest
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get list of leaders with leading score (the losers aren't used here)
|
|
|
|
|
|
|
|
val evaluation = WinnersAndLosers(inquiringAssignedQuest.questNameInstance)
|
|
|
|
|
|
|
|
if (evaluation.winners.isEmpty()) //Only show leaders if there are some
|
|
|
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val listOfLeadersAsTranslatedString = evaluation.winners.joinToString(separator = ", ") { it.assignee.tr() }
|
|
|
|
|
|
|
|
fun getScoreString(name: String, score: Int) = "[$name] with [$score] [$scoreDescriptor]".tr()
|
|
|
|
|
|
|
|
val leadersString = getScoreString(listOfLeadersAsTranslatedString, evaluation.maxScore)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (inquiringAssignedQuest in evaluation.winners)
|
|
|
|
|
|
|
|
return "Current leader(s): [$leadersString]"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val yourScoreString = getScoreString(inquiringAssignedQuest.assignee, getScoreForQuest(inquiringAssignedQuest))
|
|
|
|
|
|
|
|
return "Current leader(s): [$leadersString], you: [$yourScoreString]"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Gets notified a barbarian camp in [location] has been cleared by [civInfo].
|
|
|
|
* Gets notified a barbarian camp in [location] has been cleared by [civInfo].
|
|
|
@ -501,8 +579,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
* multiple civilizations, so after this notification all matching quests are removed.
|
|
|
|
* multiple civilizations, so after this notification all matching quests are removed.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
fun barbarianCampCleared(civInfo: Civilization, location: Vector2) {
|
|
|
|
fun barbarianCampCleared(civInfo: Civilization, location: Vector2) {
|
|
|
|
val matchingQuests = assignedQuests.asSequence()
|
|
|
|
val matchingQuests = getAssignedQuestsOfName(QuestName.ClearBarbarianCamp)
|
|
|
|
.filter { it.questName == QuestName.ClearBarbarianCamp.value }
|
|
|
|
|
|
|
|
.filter { it.data1.toInt() == location.x.toInt() && it.data2.toInt() == location.y.toInt() }
|
|
|
|
.filter { it.data1.toInt() == location.x.toInt() && it.data2.toInt() == location.y.toInt() }
|
|
|
|
|
|
|
|
|
|
|
|
val winningQuest = matchingQuests.filter { it.assignee == civInfo.civName }.firstOrNull()
|
|
|
|
val winningQuest = matchingQuests.filter { it.assignee == civInfo.civName }.firstOrNull()
|
|
|
@ -516,8 +593,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
* Gets notified the city state [cityState] was just conquered by [attacker].
|
|
|
|
* Gets notified the city state [cityState] was just conquered by [attacker].
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
fun cityStateConquered(cityState: Civilization, attacker: Civilization) {
|
|
|
|
fun cityStateConquered(cityState: Civilization, attacker: Civilization) {
|
|
|
|
val matchingQuests = assignedQuests.asSequence()
|
|
|
|
val matchingQuests = getAssignedQuestsOfName(QuestName.ConquerCityState)
|
|
|
|
.filter { it.questName == QuestName.ConquerCityState.value }
|
|
|
|
|
|
|
|
.filter { it.data1 == cityState.civName && it.assignee == attacker.civName }
|
|
|
|
.filter { it.data1 == cityState.civName && it.assignee == attacker.civName }
|
|
|
|
|
|
|
|
|
|
|
|
for (quest in matchingQuests)
|
|
|
|
for (quest in matchingQuests)
|
|
|
@ -530,8 +606,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
* Gets notified the city state [cityState] was just bullied by [bully].
|
|
|
|
* Gets notified the city state [cityState] was just bullied by [bully].
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
fun cityStateBullied(cityState: Civilization, bully: Civilization) {
|
|
|
|
fun cityStateBullied(cityState: Civilization, bully: Civilization) {
|
|
|
|
val matchingQuests = assignedQuests.asSequence()
|
|
|
|
val matchingQuests = getAssignedQuestsOfName(QuestName.BullyCityState)
|
|
|
|
.filter { it.questName == QuestName.BullyCityState.value }
|
|
|
|
|
|
|
|
.filter { it.data1 == cityState.civName && it.assignee == bully.civName}
|
|
|
|
.filter { it.data1 == cityState.civName && it.assignee == bully.civName}
|
|
|
|
|
|
|
|
|
|
|
|
for (quest in matchingQuests)
|
|
|
|
for (quest in matchingQuests)
|
|
|
@ -540,29 +615,30 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
assignedQuests.removeAll(matchingQuests)
|
|
|
|
assignedQuests.removeAll(matchingQuests)
|
|
|
|
|
|
|
|
|
|
|
|
// What idiots haha oh wait that's us
|
|
|
|
// What idiots haha oh wait that's us
|
|
|
|
if (civInfo == cityState) {
|
|
|
|
if (civ != cityState) return
|
|
|
|
|
|
|
|
|
|
|
|
// Revoke most quest types from the bully
|
|
|
|
// Revoke most quest types from the bully
|
|
|
|
val revokedQuests = assignedQuests.asSequence()
|
|
|
|
val revokedQuests = getAssignedQuestsFor(bully.civName)
|
|
|
|
.filter { it.assignee == bully.civName && (it.isIndividual() || it.questName == QuestName.Invest.value) }
|
|
|
|
.filter { it.isIndividual() || it.questNameInstance == QuestName.Invest }
|
|
|
|
|
|
|
|
.toList()
|
|
|
|
assignedQuests.removeAll(revokedQuests)
|
|
|
|
assignedQuests.removeAll(revokedQuests)
|
|
|
|
if (revokedQuests.count() > 0)
|
|
|
|
if (revokedQuests.isEmpty()) return
|
|
|
|
bully.addNotification("[${civInfo.civName}] cancelled the quests they had given you because you demanded tribute from them.",
|
|
|
|
bully.addNotification("[${civ.civName}] cancelled the quests they had given you because you demanded tribute from them.",
|
|
|
|
DiplomacyAction(civInfo.civName),
|
|
|
|
DiplomacyAction(civ.civName),
|
|
|
|
NotificationCategory.Diplomacy, civInfo.civName, "OtherIcons/Quest")
|
|
|
|
NotificationCategory.Diplomacy, civ.civName, "OtherIcons/Quest")
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Gets notified when we are attacked, for war with major pseudo-quest */
|
|
|
|
/** Gets notified when we are attacked, for war with major pseudo-quest */
|
|
|
|
fun wasAttackedBy(attacker: Civilization) {
|
|
|
|
fun wasAttackedBy(attacker: Civilization) {
|
|
|
|
// Set target number units to kill
|
|
|
|
// Set target number units to kill
|
|
|
|
val totalMilitaryUnits = attacker.units.getCivUnits().count { !it.isCivilian() }
|
|
|
|
val totalMilitaryUnits = attacker.units.getCivUnits().count { !it.isCivilian() }
|
|
|
|
val unitsToKill = max(3, totalMilitaryUnits / 4)
|
|
|
|
val unitsToKill = (totalMilitaryUnits / 4).coerceAtMost(3)
|
|
|
|
unitsToKillForCiv[attacker.civName] = unitsToKill
|
|
|
|
unitsToKillForCiv[attacker.civName] = unitsToKill
|
|
|
|
|
|
|
|
|
|
|
|
// Ask for assistance
|
|
|
|
// Ask for assistance
|
|
|
|
val location = civInfo.getCapital(firstCityIfNoCapital = true)?.location
|
|
|
|
val location = civ.getCapital(firstCityIfNoCapital = true)?.location
|
|
|
|
for (thirdCiv in civInfo.getKnownCivs()) {
|
|
|
|
for (thirdCiv in civ.getKnownCivs()) {
|
|
|
|
if (!thirdCiv.isMajorCiv() || thirdCiv.isDefeated() || thirdCiv.isAtWarWith(civInfo))
|
|
|
|
if (!thirdCiv.isMajorCiv() || thirdCiv.isDefeated() || thirdCiv.isAtWarWith(civ))
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
notifyAskForAssistance(thirdCiv, attacker.civName, unitsToKill, location)
|
|
|
|
notifyAskForAssistance(thirdCiv, attacker.civName, unitsToKill, location)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -570,11 +646,11 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
|
|
|
|
|
|
|
|
private fun notifyAskForAssistance(assignee: Civilization, attackerName: String, unitsToKill: Int, location: Vector2?) {
|
|
|
|
private fun notifyAskForAssistance(assignee: Civilization, attackerName: String, unitsToKill: Int, location: Vector2?) {
|
|
|
|
if (attackerName == assignee.civName) return // No "Hey Bob help us against Bob"
|
|
|
|
if (attackerName == assignee.civName) return // No "Hey Bob help us against Bob"
|
|
|
|
val message = "[${civInfo.civName}] is being attacked by [$attackerName]!" +
|
|
|
|
val message = "[${civ.civName}] is being attacked by [$attackerName]!" +
|
|
|
|
// Space relevant in template!
|
|
|
|
// Space relevant in template!
|
|
|
|
" Kill [$unitsToKill] of the attacker's military units and they will be immensely grateful."
|
|
|
|
" Kill [$unitsToKill] of the attacker's military units and they will be immensely grateful."
|
|
|
|
// Note: that LocationAction pseudo-constructor is able to filter out null location(s), no need for `if`
|
|
|
|
// Note: that LocationAction pseudo-constructor is able to filter out null location(s), no need for `if`
|
|
|
|
assignee.addNotification(message, LocationAction(location), NotificationCategory.Diplomacy, civInfo.civName, "OtherIcons/Quest")
|
|
|
|
assignee.addNotification(message, LocationAction(location), NotificationCategory.Diplomacy, civ.civName, "OtherIcons/Quest")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Gets notified when [killed]'s military unit was killed by [killer], for war with major pseudo-quest */
|
|
|
|
/** Gets notified when [killed]'s military unit was killed by [killer], for war with major pseudo-quest */
|
|
|
@ -582,21 +658,20 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
if (!warWithMajorActive(killed)) return
|
|
|
|
if (!warWithMajorActive(killed)) return
|
|
|
|
|
|
|
|
|
|
|
|
// No credit if we're at war or haven't met
|
|
|
|
// No credit if we're at war or haven't met
|
|
|
|
if (!civInfo.knows(killer) || civInfo.isAtWarWith(killer)) return
|
|
|
|
if (!civ.knows(killer) || civ.isAtWarWith(killer)) return
|
|
|
|
|
|
|
|
|
|
|
|
// Make the map if we haven't already
|
|
|
|
// Make the map if we haven't already
|
|
|
|
if (unitsKilledFromCiv[killed.civName] == null)
|
|
|
|
val unitsKilledFromCivEntry = unitsKilledFromCiv.getOrPut(killed.civName) { HashMap() }
|
|
|
|
unitsKilledFromCiv[killed.civName] = HashMap()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Update kill count
|
|
|
|
// Update kill count
|
|
|
|
val updatedKillCount = 1 + (unitsKilledFromCiv[killed.civName]!![killer.civName] ?: 0)
|
|
|
|
val updatedKillCount = 1 + (unitsKilledFromCivEntry[killer.civName] ?: 0)
|
|
|
|
unitsKilledFromCiv[killed.civName]!![killer.civName] = updatedKillCount
|
|
|
|
unitsKilledFromCivEntry[killer.civName] = updatedKillCount
|
|
|
|
|
|
|
|
|
|
|
|
// Quest complete?
|
|
|
|
// Quest complete?
|
|
|
|
if (updatedKillCount >= unitsToKillForCiv[killed.civName]!!) {
|
|
|
|
if (updatedKillCount >= unitsToKillForCiv[killed.civName]!!) {
|
|
|
|
killer.addNotification("[${civInfo.civName}] is deeply grateful for your assistance in the war against [${killed.civName}]!",
|
|
|
|
killer.addNotification("[${civ.civName}] is deeply grateful for your assistance in the war against [${killed.civName}]!",
|
|
|
|
DiplomacyAction(civInfo.civName), NotificationCategory.Diplomacy, civInfo.civName, "OtherIcons/Quest")
|
|
|
|
DiplomacyAction(civ.civName), NotificationCategory.Diplomacy, civ.civName, "OtherIcons/Quest")
|
|
|
|
civInfo.getDiplomacyManager(killer).addInfluence(100f) // yikes
|
|
|
|
civ.getDiplomacyManager(killer).addInfluence(100f) // yikes
|
|
|
|
endWarWithMajorQuest(killed)
|
|
|
|
endWarWithMajorQuest(killed)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -604,28 +679,28 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
/** Called when a major civ meets the city-state for the first time. Mainly for war with major pseudo-quest. */
|
|
|
|
/** Called when a major civ meets the city-state for the first time. Mainly for war with major pseudo-quest. */
|
|
|
|
fun justMet(otherCiv: Civilization) {
|
|
|
|
fun justMet(otherCiv: Civilization) {
|
|
|
|
if (unitsToKillForCiv.isEmpty()) return
|
|
|
|
if (unitsToKillForCiv.isEmpty()) return
|
|
|
|
val location = civInfo.getCapital(firstCityIfNoCapital = true)?.location
|
|
|
|
val location = civ.getCapital(firstCityIfNoCapital = true)?.location
|
|
|
|
for ((attackerName, unitsToKill) in unitsToKillForCiv)
|
|
|
|
for ((attackerName, unitsToKill) in unitsToKillForCiv)
|
|
|
|
notifyAskForAssistance(otherCiv, attackerName, unitsToKill, location)
|
|
|
|
notifyAskForAssistance(otherCiv, attackerName, unitsToKill, location)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Ends War with Major pseudo-quests that aren't relevant any longer */
|
|
|
|
/** Ends War with Major pseudo-quests that aren't relevant any longer */
|
|
|
|
private fun tryEndWarWithMajorQuests() {
|
|
|
|
private fun tryEndWarWithMajorQuests() {
|
|
|
|
for (attacker in unitsToKillForCiv.keys.map { civInfo.gameInfo.getCivilization(it) }) {
|
|
|
|
for (attacker in unitsToKillForCiv.keys.map { civ.gameInfo.getCivilization(it) }) {
|
|
|
|
if (civInfo.isDefeated()
|
|
|
|
if (civ.isDefeated()
|
|
|
|
|| attacker.isDefeated()
|
|
|
|
|| attacker.isDefeated()
|
|
|
|
|| !civInfo.isAtWarWith(attacker)) {
|
|
|
|
|| !civ.isAtWarWith(attacker)) {
|
|
|
|
endWarWithMajorQuest(attacker)
|
|
|
|
endWarWithMajorQuest(attacker)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun endWarWithMajorQuest(attacker: Civilization) {
|
|
|
|
private fun endWarWithMajorQuest(attacker: Civilization) {
|
|
|
|
for (thirdCiv in civInfo.getKnownCivs().filterNot { it.isDefeated() || it == attacker || it.isAtWarWith(civInfo) }) {
|
|
|
|
for (thirdCiv in civ.getKnownCivs().filterNot { it.isDefeated() || it == attacker || it.isAtWarWith(civ) }) {
|
|
|
|
if (unitsKilledSoFar(attacker, thirdCiv) >= unitsToKill(attacker)) // Don't show the notification to the one who won the quest
|
|
|
|
if (unitsKilledSoFar(attacker, thirdCiv) >= unitsToKill(attacker)) // Don't show the notification to the one who won the quest
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
thirdCiv.addNotification("[${civInfo.civName}] no longer needs your assistance against [${attacker.civName}].",
|
|
|
|
thirdCiv.addNotification("[${civ.civName}] no longer needs your assistance against [${attacker.civName}].",
|
|
|
|
DiplomacyAction(civInfo.civName), NotificationCategory.Diplomacy, civInfo.civName, "OtherIcons/Quest")
|
|
|
|
DiplomacyAction(civ.civName), NotificationCategory.Diplomacy, civ.civName, "OtherIcons/Quest")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unitsToKillForCiv.remove(attacker.civName)
|
|
|
|
unitsToKillForCiv.remove(attacker.civName)
|
|
|
|
unitsKilledFromCiv.remove(attacker.civName)
|
|
|
|
unitsKilledFromCiv.remove(attacker.civName)
|
|
|
@ -648,8 +723,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
* Gets notified when given gold by [donorCiv].
|
|
|
|
* Gets notified when given gold by [donorCiv].
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
fun receivedGoldGift(donorCiv: Civilization) {
|
|
|
|
fun receivedGoldGift(donorCiv: Civilization) {
|
|
|
|
val matchingQuests = assignedQuests.asSequence()
|
|
|
|
val matchingQuests = getAssignedQuestsOfName(QuestName.GiveGold)
|
|
|
|
.filter { it.questName == QuestName.GiveGold.value }
|
|
|
|
|
|
|
|
.filter { it.assignee == donorCiv.civName }
|
|
|
|
.filter { it.assignee == donorCiv.civName }
|
|
|
|
|
|
|
|
|
|
|
|
for (quest in matchingQuests)
|
|
|
|
for (quest in matchingQuests)
|
|
|
@ -663,23 +737,23 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private fun getQuestWeight(questName: String): Float {
|
|
|
|
private fun getQuestWeight(questName: String): Float {
|
|
|
|
var weight = 1f
|
|
|
|
var weight = 1f
|
|
|
|
val quest = civInfo.gameInfo.ruleset.quests[questName] ?: return 0f
|
|
|
|
val quest = ruleset.quests[questName] ?: return 0f
|
|
|
|
|
|
|
|
|
|
|
|
val personalityWeight = quest.weightForCityStateType[civInfo.cityStatePersonality.name]
|
|
|
|
val personalityWeight = quest.weightForCityStateType[civ.cityStatePersonality.name]
|
|
|
|
if (personalityWeight != null) weight *= personalityWeight
|
|
|
|
if (personalityWeight != null) weight *= personalityWeight
|
|
|
|
|
|
|
|
|
|
|
|
val traitWeight = quest.weightForCityStateType[civInfo.cityStateType.name]
|
|
|
|
val traitWeight = quest.weightForCityStateType[civ.cityStateType.name]
|
|
|
|
if (traitWeight != null) weight *= traitWeight
|
|
|
|
if (traitWeight != null) weight *= traitWeight
|
|
|
|
return weight
|
|
|
|
return weight
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//region get-quest-target
|
|
|
|
//region get-quest-target
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Returns a random [Tile] containing a Barbarian encampment within 8 tiles of [civInfo]
|
|
|
|
* Returns a random [Tile] containing a Barbarian encampment within 8 tiles of [civ]
|
|
|
|
* to be destroyed
|
|
|
|
* to be destroyed
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private fun getBarbarianEncampmentForQuest(): Tile? {
|
|
|
|
private fun getBarbarianEncampmentForQuest(): Tile? {
|
|
|
|
val encampments = civInfo.getCapital()!!.getCenterTile().getTilesInDistance(8)
|
|
|
|
val encampments = civ.getCapital()!!.getCenterTile().getTilesInDistance(8)
|
|
|
|
.filter { it.improvement == Constants.barbarianEncampment }.toList()
|
|
|
|
.filter { it.improvement == Constants.barbarianEncampment }.toList()
|
|
|
|
|
|
|
|
|
|
|
|
if (encampments.isNotEmpty())
|
|
|
|
if (encampments.isNotEmpty())
|
|
|
@ -691,15 +765,15 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Returns a random resource to be connected to the [challenger]'s trade route as a quest.
|
|
|
|
* Returns a random resource to be connected to the [challenger]'s trade route as a quest.
|
|
|
|
* The resource must be a [ResourceType.Luxury] or [ResourceType.Strategic], must not be owned
|
|
|
|
* The resource must be a [ResourceType.Luxury] or [ResourceType.Strategic], must not be owned
|
|
|
|
* by the [civInfo] and the [challenger], and must be viewable by the [challenger];
|
|
|
|
* by the [civ] and the [challenger], and must be viewable by the [challenger];
|
|
|
|
* if none exists, it returns null.
|
|
|
|
* if none exists, it returns null.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private fun getResourceForQuest(challenger: Civilization): TileResource? {
|
|
|
|
private fun getResourceForQuest(challenger: Civilization): TileResource? {
|
|
|
|
val ownedByCityStateResources = civInfo.detailedCivResources.map { it.resource }
|
|
|
|
val ownedByCityStateResources = civ.detailedCivResources.map { it.resource }
|
|
|
|
val ownedByMajorResources = challenger.detailedCivResources.map { it.resource }
|
|
|
|
val ownedByMajorResources = challenger.detailedCivResources.map { it.resource }
|
|
|
|
|
|
|
|
|
|
|
|
val resourcesOnMap = civInfo.gameInfo.tileMap.values.asSequence().mapNotNull { it.resource }.distinct()
|
|
|
|
val resourcesOnMap = civ.gameInfo.tileMap.values.asSequence().mapNotNull { it.resource }.distinct()
|
|
|
|
val viewableResourcesForChallenger = resourcesOnMap.map { civInfo.gameInfo.ruleset.tileResources[it]!! }
|
|
|
|
val viewableResourcesForChallenger = resourcesOnMap.map { ruleset.tileResources[it]!! }
|
|
|
|
.filter { it.revealedBy == null || challenger.tech.isResearched(it.revealedBy!!) }
|
|
|
|
.filter { it.revealedBy == null || challenger.tech.isResearched(it.revealedBy!!) }
|
|
|
|
|
|
|
|
|
|
|
|
val notOwnedResources = viewableResourcesForChallenger.filter {
|
|
|
|
val notOwnedResources = viewableResourcesForChallenger.filter {
|
|
|
@ -715,18 +789,18 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun getWonderToBuildForQuest(challenger: Civilization): Building? {
|
|
|
|
private fun getWonderToBuildForQuest(challenger: Civilization): Building? {
|
|
|
|
val startingEra = civInfo.gameInfo.ruleset.eras[civInfo.gameInfo.gameParameters.startingEra]!!
|
|
|
|
val startingEra = ruleset.eras[civ.gameInfo.gameParameters.startingEra]!!
|
|
|
|
val wonders = civInfo.gameInfo.ruleset.buildings.values
|
|
|
|
val wonders = ruleset.buildings.values
|
|
|
|
.filter { building ->
|
|
|
|
.filter { building ->
|
|
|
|
// Buildable wonder
|
|
|
|
// Buildable wonder
|
|
|
|
building.isWonder
|
|
|
|
building.isWonder
|
|
|
|
&& challenger.tech.isResearched(building)
|
|
|
|
&& challenger.tech.isResearched(building)
|
|
|
|
&& civInfo.gameInfo.getCities().none { it.cityConstructions.isBuilt(building.name) }
|
|
|
|
&& civ.gameInfo.getCities().none { it.cityConstructions.isBuilt(building.name) }
|
|
|
|
// Can't be disabled
|
|
|
|
// Can't be disabled
|
|
|
|
&& building.name !in startingEra.startingObsoleteWonders
|
|
|
|
&& building.name !in startingEra.startingObsoleteWonders
|
|
|
|
&& (civInfo.gameInfo.isReligionEnabled() || !building.hasUnique(UniqueType.HiddenWithoutReligion))
|
|
|
|
&& (civ.gameInfo.isReligionEnabled() || !building.hasUnique(UniqueType.HiddenWithoutReligion))
|
|
|
|
// Can't be more than 25% built anywhere
|
|
|
|
// Can't be more than 25% built anywhere
|
|
|
|
&& civInfo.gameInfo.getCities().none {
|
|
|
|
&& civ.gameInfo.getCities().none {
|
|
|
|
it.cityConstructions.getWorkDone(building.name) * 3 > it.cityConstructions.getRemainingWork(building.name) }
|
|
|
|
it.cityConstructions.getWorkDone(building.name) * 3 > it.cityConstructions.getRemainingWork(building.name) }
|
|
|
|
// Can't be a unique wonder
|
|
|
|
// Can't be a unique wonder
|
|
|
|
&& building.uniqueTo == null
|
|
|
|
&& building.uniqueTo == null
|
|
|
@ -742,7 +816,7 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
* Returns a random Natural Wonder not yet discovered by [challenger].
|
|
|
|
* Returns a random Natural Wonder not yet discovered by [challenger].
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private fun getNaturalWonderToFindForQuest(challenger: Civilization): String? {
|
|
|
|
private fun getNaturalWonderToFindForQuest(challenger: Civilization): String? {
|
|
|
|
val naturalWondersToFind = civInfo.gameInfo.tileMap.naturalWonders.subtract(challenger.naturalWonders)
|
|
|
|
val naturalWondersToFind = civ.gameInfo.tileMap.naturalWonders.subtract(challenger.naturalWonders)
|
|
|
|
|
|
|
|
|
|
|
|
if (naturalWondersToFind.isNotEmpty())
|
|
|
|
if (naturalWondersToFind.isNotEmpty())
|
|
|
|
return naturalWondersToFind.random()
|
|
|
|
return naturalWondersToFind.random()
|
|
|
@ -751,20 +825,20 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Returns a Great Person [BaseUnit] that is not owned by both the [challenger] and the [civInfo]
|
|
|
|
* Returns a Great Person [BaseUnit] that is not owned by both the [challenger] and the [civ]
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private fun getGreatPersonForQuest(challenger: Civilization): BaseUnit? {
|
|
|
|
private fun getGreatPersonForQuest(challenger: Civilization): BaseUnit? {
|
|
|
|
val ruleSet = civInfo.gameInfo.ruleset
|
|
|
|
val ruleset = ruleset // omit if the accessor should be converted to a transient field
|
|
|
|
|
|
|
|
|
|
|
|
val challengerGreatPeople = challenger.units.getCivGreatPeople().map { it.baseUnit.getReplacedUnit(ruleSet) }
|
|
|
|
val challengerGreatPeople = challenger.units.getCivGreatPeople().map { it.baseUnit.getReplacedUnit(ruleset) }
|
|
|
|
val cityStateGreatPeople = civInfo.units.getCivGreatPeople().map { it.baseUnit.getReplacedUnit(ruleSet) }
|
|
|
|
val cityStateGreatPeople = civ.units.getCivGreatPeople().map { it.baseUnit.getReplacedUnit(ruleset) }
|
|
|
|
|
|
|
|
|
|
|
|
val greatPeople = challenger.greatPeople.getGreatPeople()
|
|
|
|
val greatPeople = challenger.greatPeople.getGreatPeople()
|
|
|
|
.map { it.getReplacedUnit(ruleSet) }
|
|
|
|
.map { it.getReplacedUnit(ruleset) }
|
|
|
|
.distinct()
|
|
|
|
.distinct()
|
|
|
|
.filterNot { challengerGreatPeople.contains(it)
|
|
|
|
.filterNot { challengerGreatPeople.contains(it)
|
|
|
|
|| cityStateGreatPeople.contains(it)
|
|
|
|
|| cityStateGreatPeople.contains(it)
|
|
|
|
|| (it.hasUnique(UniqueType.HiddenWithoutReligion) && !civInfo.gameInfo.isReligionEnabled()) }
|
|
|
|
|| (it.hasUnique(UniqueType.HiddenWithoutReligion) && !civ.gameInfo.isReligionEnabled()) }
|
|
|
|
.toList()
|
|
|
|
.toList()
|
|
|
|
|
|
|
|
|
|
|
|
if (greatPeople.isNotEmpty())
|
|
|
|
if (greatPeople.isNotEmpty())
|
|
|
@ -788,65 +862,77 @@ class QuestManager : IsPartOfGameInfoSerialization {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Returns a city-state [Civilization] that [civInfo] wants to target for hostile quests
|
|
|
|
* Returns a city-state [Civilization] that [civ] wants to target for hostile quests
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private fun getCityStateTarget(challenger: Civilization): Civilization? {
|
|
|
|
private fun getCityStateTarget(challenger: Civilization): Civilization? {
|
|
|
|
val closestProximity = civInfo.gameInfo.getAliveCityStates()
|
|
|
|
val closestProximity = civ.gameInfo.getAliveCityStates()
|
|
|
|
.mapNotNull { civInfo.proximity[it.civName] }.filter { it != Proximity.None }.minByOrNull { it.ordinal }
|
|
|
|
.mapNotNull { civ.proximity[it.civName] }.filter { it != Proximity.None }.minByOrNull { it.ordinal }
|
|
|
|
|
|
|
|
|
|
|
|
if (closestProximity == null || closestProximity == Proximity.Distant) // None close enough
|
|
|
|
if (closestProximity == null || closestProximity == Proximity.Distant) // None close enough
|
|
|
|
return null
|
|
|
|
return null
|
|
|
|
|
|
|
|
|
|
|
|
val validTargets = civInfo.getKnownCivs().filter { it.isCityState() && challenger.knows(it)
|
|
|
|
val validTargets = civ.getKnownCivs().filter { it.isCityState() && challenger.knows(it)
|
|
|
|
&& civInfo.proximity[it.civName] == closestProximity }
|
|
|
|
&& civ.proximity[it.civName] == closestProximity }
|
|
|
|
|
|
|
|
|
|
|
|
return validTargets.toList().randomOrNull()
|
|
|
|
return validTargets.toList().randomOrNull()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Returns a [Civilization] of the civ that most recently bullied [civInfo].
|
|
|
|
/** Returns a [Civilization] of the civ that most recently bullied [civ].
|
|
|
|
* Note: forgets after 20 turns has passed! */
|
|
|
|
* Note: forgets after 20 turns has passed! */
|
|
|
|
private fun getMostRecentBully(): String? {
|
|
|
|
private fun getMostRecentBully(): String? {
|
|
|
|
val bullies = civInfo.diplomacy.values.filter { it.hasFlag(DiplomacyFlags.Bullied)}
|
|
|
|
val bullies = civ.diplomacy.values.filter { it.hasFlag(DiplomacyFlags.Bullied) }
|
|
|
|
return bullies.maxByOrNull { it.getFlag(DiplomacyFlags.Bullied) }?.otherCivName
|
|
|
|
return bullies.maxByOrNull { it.getFlag(DiplomacyFlags.Bullied) }?.otherCivName
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//endregion
|
|
|
|
//endregion
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AssignedQuest(val questName: String = "",
|
|
|
|
class AssignedQuest(
|
|
|
|
|
|
|
|
val questName: String = "",
|
|
|
|
val assigner: String = "",
|
|
|
|
val assigner: String = "",
|
|
|
|
val assignee: String = "",
|
|
|
|
val assignee: String = "",
|
|
|
|
val assignedOnTurn: Int = 0,
|
|
|
|
val assignedOnTurn: Int = 0,
|
|
|
|
val data1: String = "",
|
|
|
|
val data1: String = "",
|
|
|
|
val data2: String = "") : IsPartOfGameInfoSerialization {
|
|
|
|
val data2: String = ""
|
|
|
|
|
|
|
|
) : IsPartOfGameInfoSerialization {
|
|
|
|
|
|
|
|
|
|
|
|
@Transient
|
|
|
|
@Transient
|
|
|
|
lateinit var gameInfo: GameInfo
|
|
|
|
private lateinit var gameInfo: GameInfo
|
|
|
|
|
|
|
|
|
|
|
|
fun isIndividual(): Boolean = !isGlobal()
|
|
|
|
@Transient
|
|
|
|
fun isGlobal(): Boolean = gameInfo.ruleset.quests[questName]!!.isGlobal()
|
|
|
|
private lateinit var questObject: Quest
|
|
|
|
@Suppress("MemberVisibilityCanBePrivate")
|
|
|
|
|
|
|
|
fun doesExpire(): Boolean = gameInfo.ruleset.quests[questName]!!.duration > 0
|
|
|
|
|
|
|
|
fun isExpired(): Boolean = doesExpire() && getRemainingTurns() == 0
|
|
|
|
|
|
|
|
@Suppress("MemberVisibilityCanBePrivate")
|
|
|
|
|
|
|
|
fun getDuration(): Int = (gameInfo.speed.modifier * gameInfo.ruleset.quests[questName]!!.duration).toInt()
|
|
|
|
|
|
|
|
fun getRemainingTurns(): Int = max(0, (assignedOnTurn + getDuration()) - gameInfo.turns)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun getDescription(): String {
|
|
|
|
val questNameInstance get() = questObject.questNameInstance
|
|
|
|
val quest = gameInfo.ruleset.quests[questName]!!
|
|
|
|
|
|
|
|
return quest.description.fillPlaceholders(data1)
|
|
|
|
internal fun setTransients(gameInfo: GameInfo, quest: Quest? = null) {
|
|
|
|
|
|
|
|
this.gameInfo = gameInfo
|
|
|
|
|
|
|
|
questObject = quest ?: gameInfo.ruleset.quests[questName]!!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun isIndividual(): Boolean = !isGlobal()
|
|
|
|
|
|
|
|
fun isGlobal(): Boolean = questObject.isGlobal()
|
|
|
|
|
|
|
|
@Suppress("MemberVisibilityCanBePrivate")
|
|
|
|
|
|
|
|
fun doesExpire(): Boolean = questObject.duration > 0
|
|
|
|
|
|
|
|
fun isExpired(): Boolean = doesExpire() && getRemainingTurns() == 0
|
|
|
|
|
|
|
|
@Suppress("MemberVisibilityCanBePrivate")
|
|
|
|
|
|
|
|
fun getDuration(): Int = (gameInfo.speed.modifier * questObject.duration).toInt()
|
|
|
|
|
|
|
|
fun getRemainingTurns(): Int = (assignedOnTurn + getDuration() - gameInfo.turns).coerceAtLeast(0)
|
|
|
|
|
|
|
|
fun getInfluence() = questObject.influence
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun getDescription(): String = questObject.description.fillPlaceholders(data1)
|
|
|
|
|
|
|
|
|
|
|
|
fun onClickAction() {
|
|
|
|
fun onClickAction() {
|
|
|
|
when (questName) {
|
|
|
|
when (questNameInstance) {
|
|
|
|
QuestName.ClearBarbarianCamp.value -> {
|
|
|
|
QuestName.ClearBarbarianCamp -> {
|
|
|
|
GUI.resetToWorldScreen()
|
|
|
|
GUI.resetToWorldScreen()
|
|
|
|
GUI.getMap().setCenterPosition(Vector2(data1.toFloat(), data2.toFloat()), selectUnit = false)
|
|
|
|
GUI.getMap().setCenterPosition(Vector2(data1.toFloat(), data2.toFloat()), selectUnit = false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QuestName.Route.value -> {
|
|
|
|
QuestName.Route -> {
|
|
|
|
GUI.resetToWorldScreen()
|
|
|
|
GUI.resetToWorldScreen()
|
|
|
|
GUI.getMap().setCenterPosition(gameInfo.getCivilization(assigner).getCapital()!!.location, selectUnit = false)
|
|
|
|
GUI.getMap().setCenterPosition(gameInfo.getCivilization(assigner).getCapital()!!.location, selectUnit = false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else -> Unit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|