Added specific icons to certain notification types

This commit is contained in:
Yair Morgenstern 2021-03-19 11:26:54 +02:00
parent ba51222841
commit 50d5b0d7ce
22 changed files with 1498 additions and 1409 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 866 KiB

After

Width:  |  Height:  |  Size: 874 KiB

View File

@ -4,7 +4,6 @@ import java.util.*
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-android-extensions")
}
android {

View File

@ -171,11 +171,11 @@ class GameInfo {
if (tiles.size < 3) {
for (tile in tiles) {
val unitName = tile.militaryUnit!!.name
thisPlayer.addNotification("An enemy [$unitName] was spotted $inOrNear our territory", tile.position, Color.RED)
thisPlayer.addNotification("An enemy [$unitName] was spotted $inOrNear our territory", tile.position, NotificationType.War)
}
} else {
val positions = tiles.map { it.position }
thisPlayer.addNotification("[${positions.size}] enemy units were spotted $inOrNear our territory", Color.RED, LocationAction(positions))
thisPlayer.addNotification("[${positions.size}] enemy units were spotted $inOrNear our territory", NotificationType.War, LocationAction(positions))
}
}

View File

@ -6,6 +6,7 @@ import com.unciv.UncivGame
import com.unciv.logic.city.CityConstructions
import com.unciv.logic.city.PerpetualConstruction
import com.unciv.logic.civilization.CityAction
import com.unciv.logic.civilization.NotificationType
import com.unciv.logic.civilization.PlayerType
import com.unciv.logic.map.BFS
import com.unciv.models.ruleset.Building
@ -86,7 +87,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
// Nobody can plan 30 turns ahead, I don't care how cost-efficient you are.
else theChosenOne = relativeCostEffectiveness.minBy { it.remainingWork }!!.choice
civInfo.addNotification("Work has started on [$theChosenOne]", Color.BROWN, CityAction(cityInfo.location))
civInfo.addNotification("Work has started on [$theChosenOne]", NotificationType.Construction, CityAction(cityInfo.location))
cityConstructions.currentConstructionFromQueue = theChosenOne
}

View File

@ -6,6 +6,7 @@ import com.unciv.UncivGame
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.NotificationType
import com.unciv.logic.civilization.PopupAlert
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
import com.unciv.logic.map.RoadStatus
@ -173,7 +174,7 @@ object Battle {
else " [" + defender.getName() + "]"
else " our [" + defender.getName() + "]"
val notificationString = attackerString + whatHappenedString + defenderString
defender.getCivInfo().addNotification(notificationString, attackedTile.position, Color.RED)
defender.getCivInfo().addNotification(notificationString, attackedTile.position, NotificationType.War)
}
}
@ -288,7 +289,7 @@ object Battle {
private fun conquerCity(city: CityInfo, attacker: ICombatant) {
val attackerCiv = attacker.getCivInfo()
attackerCiv.addNotification("We have conquered the city of [${city.name}]!", city.location, Color.RED)
attackerCiv.addNotification("We have conquered the city of [${city.name}]!", city.location, NotificationType.War)
city.getCenterTile().apply {
if (militaryUnit != null) militaryUnit!!.destroy()
@ -334,7 +335,7 @@ object Battle {
val capturedUnit = defender.unit
capturedUnit.civInfo.addNotification("An enemy [" + attacker.getName() + "] has captured our [" + defender.getName() + "]",
defender.getTile().position, Color.RED)
defender.getTile().position, NotificationType.War)
// Apparently in Civ V, captured settlers are converted to workers.
if (capturedUnit.name == Constants.settler) {
@ -432,17 +433,17 @@ object Battle {
if (attacker.isDefeated()) {
attacker.getCivInfo()
.addNotification("Our [$attackerName] was destroyed by an intercepting [$interceptorName]",
Color.RED)
NotificationType.War)
defender.getCivInfo()
.addNotification("Our [$interceptorName] intercepted and destroyed an enemy [$attackerName]",
interceptor.currentTile.position, Color.RED)
interceptor.currentTile.position, NotificationType.War)
} else {
attacker.getCivInfo()
.addNotification("Our [$attackerName] was attacked by an intercepting [$interceptorName]",
Color.RED)
NotificationType.War)
defender.getCivInfo()
.addNotification("Our [$interceptorName] intercepted and attacked an enemy [$attackerName]",
interceptor.currentTile.position, Color.RED)
interceptor.currentTile.position, NotificationType.War)
}
return
}
@ -497,8 +498,8 @@ object Battle {
// and count 1 attack for attacker but leave it in place
reduceAttackerMovementPointsAndAttacks(attacker, defender)
val notificationString = "[" + defendBaseUnit.name + "] withdrew from a [" + attackBaseUnit.name + "]"
defender.getCivInfo().addNotification(notificationString, toTile.position, Color.GREEN)
attacker.getCivInfo().addNotification(notificationString, toTile.position, Color.RED)
defender.getCivInfo().addNotification(notificationString, toTile.position, NotificationType.War)
attacker.getCivInfo().addNotification(notificationString, toTile.position, NotificationType.War)
return true
}

View File

@ -3,6 +3,7 @@ package com.unciv.logic.city
import com.badlogic.gdx.graphics.Color
import com.unciv.logic.automation.ConstructionAutomation
import com.unciv.logic.civilization.AlertType
import com.unciv.logic.civilization.NotificationType
import com.unciv.logic.civilization.PopupAlert
import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.UniqueMap
@ -312,7 +313,7 @@ class CityConstructions {
civ.addNotification("[${construction.name}] has been built in a faraway land", null, Color.BROWN)
}
} else
cityInfo.civInfo.addNotification("[${construction.name}] has been built in [" + cityInfo.name + "]", cityInfo.location, Color.BROWN)
cityInfo.civInfo.addNotification("[${construction.name}] has been built in [" + cityInfo.name + "]", cityInfo.location, NotificationType.Construction)
}
fun addBuilding(buildingName: String) {

View File

@ -2,6 +2,7 @@ package com.unciv.logic.city
import com.badlogic.gdx.graphics.Color
import com.unciv.logic.automation.Automation
import com.unciv.logic.civilization.NotificationType
import com.unciv.logic.map.TileInfo
import com.unciv.ui.utils.withItem
import com.unciv.ui.utils.withoutItem
@ -142,10 +143,8 @@ class CityExpansionManager {
fun nextTurn(culture: Float) {
cultureStored += culture.toInt()
if (cultureStored >= getCultureToNextTile()) {
if (addNewTileWithCulture())
cityInfo.civInfo.addNotification("[" + cityInfo.name + "] has expanded its borders!", cityInfo.location, Color.PURPLE)
}
if (cultureStored >= getCultureToNextTile() && addNewTileWithCulture())
cityInfo.civInfo.addNotification("[" + cityInfo.name + "] has expanded its borders!", cityInfo.location, NotificationType.Culture)
}
fun setTransients() {

View File

@ -2,6 +2,7 @@ package com.unciv.logic.city
import com.badlogic.gdx.graphics.Color
import com.unciv.logic.automation.Automation
import com.unciv.logic.civilization.NotificationType
import com.unciv.logic.map.TileInfo
import com.unciv.models.Counter
import com.unciv.ui.utils.withItem
@ -64,7 +65,7 @@ class PopulationManager {
foodStored += (getFoodToNextPopulation() * percentOfFoodCarriedOver / 100f).toInt()
population++
autoAssignPopulation()
cityInfo.civInfo.addNotification("[${cityInfo.name}] has grown!", cityInfo.location, Color.GREEN)
cityInfo.civInfo.addNotification("[${cityInfo.name}] has grown!", cityInfo.location, NotificationType.Growth)
}
}

View File

@ -553,11 +553,22 @@ class CivilizationInfo {
addNotification(text, color, LocationAction(locations))
}
fun addNotification(text: String, location: Vector2?, notificationType: NotificationType) {
val locations = if (location != null) listOf(location) else emptyList()
addNotification(text, notificationType, LocationAction(locations))
}
fun addNotification(text: String, color: Color, action: NotificationAction? = null) {
if (playerType == PlayerType.AI) return // no point in lengthening the saved game info if no one will read it
notifications.add(Notification(text, color, action))
}
fun addNotification(text: String, notificationType: NotificationType, action: NotificationAction? = null) {
if (playerType == PlayerType.AI) return // no point in lengthening the saved game info if no one will read it
notifications.add(Notification(text, notificationType, action))
}
fun addUnit(unitName: String, city: CityInfo? = null) {
if (cities.isEmpty()) return
val cityToAddTo = city ?: cities.random()

View File

@ -7,16 +7,41 @@ import com.unciv.ui.pickerscreens.TechPickerScreen
import com.unciv.ui.trade.DiplomacyScreen
import com.unciv.ui.worldscreen.WorldScreen
enum class NotificationType {
Culture,
Construction,
Growth,
War,
Trade,
Science
}
/**
* [action] is not realized as lambda, as it would be too easy to introduce references to objects
* there that should not be serialized to the saved game.
*/
open class Notification (
// default parameters necessary for json deserialization
var text: String = "",
var color: Color = Color.BLACK,
var action: NotificationAction? = null
)
open class Notification() {
var text: String=""
var color: Color?=null
var notificationType:NotificationType?=null
var action: NotificationAction? = null
// default parameters necessary for json deserialization
constructor(text: String, color: Color, action: NotificationAction?) : this() {
this.text = text
this.color = color
this.action = action
}
constructor(text: String, notificationType: NotificationType, action: NotificationAction? = null) : this() {
this.text = text
this.notificationType = notificationType
this.action = action
}
}
/** defines what to do if the user clicks on a notification */
interface NotificationAction {

View File

@ -257,7 +257,7 @@ class TechManager {
}
}
for (it in getRuleset().policyBranches.values.filter { it.era == currentEra }) {
civInfo.addNotification("[" + it.name + "] policy branch unlocked!", null, Color.PURPLE)
civInfo.addNotification("[" + it.name + "] policy branch unlocked!", NotificationType.Culture)
}
}

View File

@ -62,52 +62,57 @@ enum class DiplomaticModifiers{
}
class DiplomacyManager() {
companion object {
/** The value city-state influence can't go below */
const val MINIMUM_INFLUENCE = -60f
}
@Transient lateinit var civInfo: CivilizationInfo
// since this needs to be checked a lot during travel, putting it in a transient is a good performance booster
@Transient var hasOpenBorders=false
lateinit var otherCivName:String
@Transient
lateinit var civInfo: CivilizationInfo
// since this needs to be checked a lot during travel, putting it in a transient is a good performance booster
@Transient
var hasOpenBorders = false
lateinit var otherCivName: String
var trades = ArrayList<Trade>()
var diplomaticStatus = DiplomaticStatus.War
/** Contains various flags (declared war, promised to not settle, declined luxury trade) and the number of turns in which they will expire.
* The JSON serialize/deserialize REFUSES to deserialize hashmap keys as Enums, so I'm forced to use strings instead =(
* This is so sad Alexa play Despacito */
private var flagsCountdown = HashMap<String,Int>()
private var flagsCountdown = HashMap<String, Int>()
/** For AI. Positive is good relations, negative is bad.
* Baseline is 1 point for each turn of peace - so declaring a war upends 40 years of peace, and e.g. capturing a city can be another 30 or 40.
* As for why it's String and not DiplomaticModifier see FlagsCountdown comment */
var diplomaticModifiers = HashMap<String,Float>()
var diplomaticModifiers = HashMap<String, Float>()
/** For city-states. Influence is saved in the CITY STATE -> major civ Diplomacy, NOT in the major civ -> cty state diplomacy.
* Won't go below [MINIMUM_INFLUENCE] */
var influence = 0f
set(value) { field = max(value, MINIMUM_INFLUENCE) }
get() = if(civInfo.isAtWarWith(otherCiv())) MINIMUM_INFLUENCE else field
set(value) {
field = max(value, MINIMUM_INFLUENCE)
}
get() = if (civInfo.isAtWarWith(otherCiv())) MINIMUM_INFLUENCE else field
/** Total of each turn Science during Research Agreement */
var totalOfScienceDuringRA = 0
fun clone(): DiplomacyManager {
val toReturn = DiplomacyManager()
toReturn.otherCivName=otherCivName
toReturn.diplomaticStatus=diplomaticStatus
toReturn.otherCivName = otherCivName
toReturn.diplomaticStatus = diplomaticStatus
toReturn.trades.addAll(trades.map { it.clone() })
toReturn.influence = influence
toReturn.flagsCountdown.putAll(flagsCountdown)
toReturn.diplomaticModifiers.putAll(diplomaticModifiers)
toReturn.totalOfScienceDuringRA=totalOfScienceDuringRA
toReturn.totalOfScienceDuringRA = totalOfScienceDuringRA
return toReturn
}
constructor(civilizationInfo: CivilizationInfo, OtherCivName:String) : this() {
constructor(civilizationInfo: CivilizationInfo, OtherCivName: String) : this() {
civInfo = civilizationInfo
otherCivName = OtherCivName
updateHasOpenBorders()
@ -118,26 +123,26 @@ class DiplomacyManager() {
fun otherCivDiplomacy() = otherCiv().getDiplomacyManager(civInfo)
fun turnsToPeaceTreaty(): Int {
for(trade in trades)
for(offer in trade.ourOffers)
if(offer.name == Constants.peaceTreaty && offer.duration > 0) return offer.duration
for (trade in trades)
for (offer in trade.ourOffers)
if (offer.name == Constants.peaceTreaty && offer.duration > 0) return offer.duration
return 0
}
fun opinionOfOtherCiv() = diplomaticModifiers.values.sum()
fun relationshipLevel(): RelationshipLevel {
if(civInfo.isPlayerCivilization() && otherCiv().isPlayerCivilization())
if (civInfo.isPlayerCivilization() && otherCiv().isPlayerCivilization())
return RelationshipLevel.Neutral // People make their own choices.
if(civInfo.isPlayerCivilization())
if (civInfo.isPlayerCivilization())
return otherCiv().getDiplomacyManager(civInfo).relationshipLevel()
if(civInfo.isCityState()) {
if(influence <= -30 || civInfo.isAtWarWith(otherCiv())) return RelationshipLevel.Unforgivable
if(influence < 0) return RelationshipLevel.Enemy
if(influence >= 60 && civInfo.getAllyCiv() == otherCivName) return RelationshipLevel.Ally
if(influence >= 30) return RelationshipLevel.Friend
if (civInfo.isCityState()) {
if (influence <= -30 || civInfo.isAtWarWith(otherCiv())) return RelationshipLevel.Unforgivable
if (influence < 0) return RelationshipLevel.Enemy
if (influence >= 60 && civInfo.getAllyCiv() == otherCivName) return RelationshipLevel.Ally
if (influence >= 30) return RelationshipLevel.Friend
return RelationshipLevel.Neutral
}
@ -149,11 +154,11 @@ class DiplomacyManager() {
opinion <= -80 -> RelationshipLevel.Unforgivable
opinion <= -40 || civInfo.isAtWarWith(otherCiv()) -> RelationshipLevel.Enemy /* During wartime, the estimation in which you are held may be enemy OR unforgivable */
opinion <= -15 -> RelationshipLevel.Competitor
opinion >= 80 -> RelationshipLevel.Ally
opinion >= 40 -> RelationshipLevel.Friend
opinion >= 15 -> RelationshipLevel.Favorable
else -> RelationshipLevel.Neutral
opinion >= 80 -> RelationshipLevel.Ally
opinion >= 40 -> RelationshipLevel.Friend
opinion >= 15 -> RelationshipLevel.Favorable
else -> RelationshipLevel.Neutral
}
}
@ -176,7 +181,7 @@ class DiplomacyManager() {
// To be run from City-State DiplomacyManager, which holds the influence. Resting point for every major civ can be different.
fun getCityStateInfluenceRestingPoint(): Float {
var restingPoint = 0f
for(unique in otherCiv().getMatchingUniques("Resting point for Influence with City-States is increased by []"))
for (unique in otherCiv().getMatchingUniques("Resting point for Influence with City-States is increased by []"))
restingPoint += unique.params[0].toInt()
return restingPoint
}
@ -226,13 +231,14 @@ class DiplomacyManager() {
return max(0f, increment) * max(0f, modifier)
}
fun canDeclareWar() = turnsToPeaceTreaty()==0 && diplomaticStatus != DiplomaticStatus.War
//Used for nuke
fun canAttack() = turnsToPeaceTreaty()==0
fun canDeclareWar() = turnsToPeaceTreaty() == 0 && diplomaticStatus != DiplomaticStatus.War
fun goldPerTurn():Int{
//Used for nuke
fun canAttack() = turnsToPeaceTreaty() == 0
fun goldPerTurn(): Int {
var goldPerTurnForUs = 0
for(trade in trades) {
for (trade in trades) {
for (offer in trade.ourOffers.filter { it.type == TradeType.Gold_Per_Turn })
goldPerTurnForUs -= offer.amount
for (offer in trade.theirOffers.filter { it.type == TradeType.Gold_Per_Turn })
@ -241,7 +247,7 @@ class DiplomacyManager() {
return goldPerTurnForUs
}
fun sciencefromResearchAgreement(){
fun sciencefromResearchAgreement() {
// https://forums.civfanatics.com/resources/research-agreements-bnw.25568/
val scienceFromResearchAgreement = min(totalOfScienceDuringRA, otherCivDiplomacy().totalOfScienceDuringRA)
civInfo.tech.scienceFromResearchAgreements += scienceFromResearchAgreement
@ -253,8 +259,10 @@ class DiplomacyManager() {
fun resourcesFromTrade(): ResourceSupplyList {
val counter = ResourceSupplyList()
val resourcesMap = civInfo.gameInfo.ruleSet.tileResources
val isResourceFilter: (TradeOffer) -> Boolean = { (it.type == TradeType.Strategic_Resource || it.type == TradeType.Luxury_Resource)
&& civInfo.gameInfo.ruleSet.tileResources.containsKey(it.name) }
val isResourceFilter: (TradeOffer) -> Boolean = {
(it.type == TradeType.Strategic_Resource || it.type == TradeType.Luxury_Resource)
&& civInfo.gameInfo.ruleSet.tileResources.containsKey(it.name)
}
for (trade in trades) {
for (offer in trade.ourOffers.filter(isResourceFilter))
counter.add(resourcesMap[offer.name]!!, -offer.amount, "Trade")
@ -299,8 +307,8 @@ class DiplomacyManager() {
trades.remove(trade)
val otherCivTrades = otherCiv().getDiplomacyManager(civInfo).trades
otherCivTrades.removeAll { it.equals(trade.reverse()) }
civInfo.addNotification("One of our trades with [$otherCivName] has been cut short", null, Color.GOLD)
otherCiv().addNotification("One of our trades with [${civInfo.civName}] has been cut short", null, Color.GOLD)
civInfo.addNotification("One of our trades with [$otherCivName] has been cut short", NotificationType.Trade)
otherCiv().addNotification("One of our trades with [${civInfo.civName}] has been cut short", NotificationType.Trade)
civInfo.updateDetailedCivResources()
}
}
@ -323,7 +331,7 @@ class DiplomacyManager() {
}
}
fun nextTurn(){
fun nextTurn() {
nextTurnTrades()
removeUntenebleTrades()
updateHasOpenBorders()
@ -355,7 +363,7 @@ class DiplomacyManager() {
influence = min(restingPoint, influence + increment)
}
if(!civInfo.isDefeated()) { // don't display city state relationship notifications when the city state is currently defeated
if (!civInfo.isDefeated()) { // don't display city state relationship notifications when the city state is currently defeated
val civCapitalLocation = if (civInfo.cities.isNotEmpty()) civInfo.getCapital().location else null
if (getTurnsToRelationshipChange() == 1)
otherCiv().addNotification("Your relationship with [${civInfo.civName}] is about to degrade", civCapitalLocation, Color.GOLD)
@ -409,8 +417,8 @@ class DiplomacyManager() {
trades.remove(trade)
for (offer in trade.ourOffers.union(trade.theirOffers).filter { it.duration == 0 }) { // this was a timed trade
if (offer in trade.theirOffers)
civInfo.addNotification("[${offer.name}] from [$otherCivName] has ended", null, Color.GOLD)
else civInfo.addNotification("[${offer.name}] to [$otherCivName] has ended", null, Color.GOLD)
civInfo.addNotification("[${offer.name}] from [$otherCivName] has ended", NotificationType.Trade)
else civInfo.addNotification("[${offer.name}] to [$otherCivName] has ended", NotificationType.Trade)
civInfo.updateStatsForNextTurn() // if they were bringing us gold per turn
civInfo.updateDetailedCivResources() // if they were giving us resources
@ -457,46 +465,46 @@ class DiplomacyManager() {
}
/** Everything that happens to both sides equally when war is delcared by one side on the other */
private fun onWarDeclared(){
private fun onWarDeclared() {
diplomaticStatus = DiplomaticStatus.War
// Cancel all trades.
for(trade in trades)
for(offer in trade.theirOffers.filter { it.duration>0 })
civInfo.addNotification("["+offer.name+"] from [$otherCivName] has ended",null, Color.GOLD)
for (trade in trades)
for (offer in trade.theirOffers.filter { it.duration > 0 })
civInfo.addNotification("[" + offer.name + "] from [$otherCivName] has ended", NotificationType.Trade)
trades.clear()
updateHasOpenBorders()
setFlag(DiplomacyFlags.DeclinedPeace,10)/// AI won't propose peace for 10 turns
setFlag(DiplomacyFlags.DeclaredWar,10) // AI won't agree to trade for 10 turns
setFlag(DiplomacyFlags.DeclinedPeace, 10)/// AI won't propose peace for 10 turns
setFlag(DiplomacyFlags.DeclaredWar, 10) // AI won't agree to trade for 10 turns
removeFlag(DiplomacyFlags.BorderConflict)
}
fun declareWar(){
fun declareWar() {
val otherCiv = otherCiv()
val otherCivDiplomacy = otherCivDiplomacy()
onWarDeclared()
otherCivDiplomacy.onWarDeclared()
otherCiv.addNotification("[${civInfo.civName}] has declared war on us!",null, Color.RED)
otherCiv.popupAlerts.add(PopupAlert(AlertType.WarDeclaration,civInfo.civName))
otherCiv.addNotification("[${civInfo.civName}] has declared war on us!", NotificationType.War)
otherCiv.popupAlerts.add(PopupAlert(AlertType.WarDeclaration, civInfo.civName))
getCommonKnownCivs().forEach {
it.addNotification("[${civInfo.civName}] has declared war on [${otherCiv().civName}]!", null, Color.RED)
it.addNotification("[${civInfo.civName}] has declared war on [${otherCiv().civName}]!", NotificationType.War)
}
otherCivDiplomacy.setModifier(DiplomaticModifiers.DeclaredWarOnUs,-20f)
if(otherCiv.isCityState()) otherCivDiplomacy.influence -= 60
otherCivDiplomacy.setModifier(DiplomaticModifiers.DeclaredWarOnUs, -20f)
if (otherCiv.isCityState()) otherCivDiplomacy.influence -= 60
for(thirdCiv in civInfo.getKnownCivs()) {
for (thirdCiv in civInfo.getKnownCivs()) {
if (thirdCiv.isAtWarWith(otherCiv)) {
if (thirdCiv.isCityState()) thirdCiv.getDiplomacyManager(civInfo).influence += 10
else thirdCiv.getDiplomacyManager(civInfo).addModifier(DiplomaticModifiers.SharedEnemy, 5f)
} else thirdCiv.getDiplomacyManager(civInfo).addModifier(DiplomaticModifiers.WarMongerer, -5f)
}
if(hasFlag(DiplomacyFlags.DeclarationOfFriendship)) {
if (hasFlag(DiplomacyFlags.DeclarationOfFriendship)) {
removeFlag(DiplomacyFlags.DeclarationOfFriendship)
otherCivDiplomacy.removeModifier(DiplomaticModifiers.DeclarationOfFriendship)
for (knownCiv in civInfo.getKnownCivs()) {
@ -507,7 +515,7 @@ class DiplomacyManager() {
}
}
otherCivDiplomacy.removeFlag(DiplomacyFlags.DeclarationOfFriendship)
if(hasFlag(DiplomacyFlags.ResearchAgreement)) {
if (hasFlag(DiplomacyFlags.ResearchAgreement)) {
removeFlag(DiplomacyFlags.ResearchAgreement)
totalOfScienceDuringRA = 0
otherCivDiplomacy.totalOfScienceDuringRA = 0
@ -567,24 +575,29 @@ class DiplomacyManager() {
}
}
fun hasFlag(flag:DiplomacyFlags) = flagsCountdown.containsKey(flag.name)
fun setFlag(flag: DiplomacyFlags, amount: Int){ flagsCountdown[flag.name]=amount}
fun getFlag(flag: DiplomacyFlags) = flagsCountdown[flag.name]!!
fun removeFlag(flag: DiplomacyFlags){ flagsCountdown.remove(flag.name)}
fun addModifier(modifier: DiplomaticModifiers, amount:Float){
val modifierString = modifier.name
if(!hasModifier(modifier)) setModifier(modifier,0f)
diplomaticModifiers[modifierString] = diplomaticModifiers[modifierString]!!+amount
if(diplomaticModifiers[modifierString]==0f) diplomaticModifiers.remove(modifierString)
fun hasFlag(flag: DiplomacyFlags) = flagsCountdown.containsKey(flag.name)
fun setFlag(flag: DiplomacyFlags, amount: Int) {
flagsCountdown[flag.name] = amount
}
fun setModifier(modifier: DiplomaticModifiers, amount: Float){
fun getFlag(flag: DiplomacyFlags) = flagsCountdown[flag.name]!!
fun removeFlag(flag: DiplomacyFlags) {
flagsCountdown.remove(flag.name)
}
fun addModifier(modifier: DiplomaticModifiers, amount: Float) {
val modifierString = modifier.name
if (!hasModifier(modifier)) setModifier(modifier, 0f)
diplomaticModifiers[modifierString] = diplomaticModifiers[modifierString]!! + amount
if (diplomaticModifiers[modifierString] == 0f) diplomaticModifiers.remove(modifierString)
}
fun setModifier(modifier: DiplomaticModifiers, amount: Float) {
diplomaticModifiers[modifier.name] = amount
}
fun getModifier(modifier: DiplomaticModifiers): Float {
if(!hasModifier(modifier)) return 0f
if (!hasModifier(modifier)) return 0f
return diplomaticModifiers[modifier.name]!!
}
@ -592,18 +605,18 @@ class DiplomacyManager() {
fun hasModifier(modifier: DiplomaticModifiers) = diplomaticModifiers.containsKey(modifier.name)
/** @param amount always positive, so you don't need to think about it */
fun revertToZero(modifier: DiplomaticModifiers, amount: Float){
if(!hasModifier(modifier)) return
fun revertToZero(modifier: DiplomaticModifiers, amount: Float) {
if (!hasModifier(modifier)) return
val currentAmount = getModifier(modifier)
if(currentAmount > 0) addModifier(modifier,-amount)
else addModifier(modifier,amount)
if (currentAmount > 0) addModifier(modifier, -amount)
else addModifier(modifier, amount)
}
fun signDeclarationOfFriendship(){
setModifier(DiplomaticModifiers.DeclarationOfFriendship,35f)
otherCivDiplomacy().setModifier(DiplomaticModifiers.DeclarationOfFriendship,35f)
setFlag(DiplomacyFlags.DeclarationOfFriendship,30)
otherCivDiplomacy().setFlag(DiplomacyFlags.DeclarationOfFriendship,30)
fun signDeclarationOfFriendship() {
setModifier(DiplomaticModifiers.DeclarationOfFriendship, 35f)
otherCivDiplomacy().setModifier(DiplomaticModifiers.DeclarationOfFriendship, 35f)
setFlag(DiplomacyFlags.DeclarationOfFriendship, 30)
otherCivDiplomacy().setFlag(DiplomacyFlags.DeclarationOfFriendship, 30)
if (otherCiv().playerType == PlayerType.Human)
otherCiv().addNotification("[${civInfo.civName}] and [${otherCiv().civName}] have signed the Declaration of Friendship!", null, Color.WHITE)
@ -613,10 +626,10 @@ class DiplomacyManager() {
}
}
fun setFriendshipBasedModifier(){
fun setFriendshipBasedModifier() {
removeModifier(DiplomaticModifiers.DeclaredFriendshipWithOurAllies)
removeModifier(DiplomaticModifiers.DeclaredFriendshipWithOurEnemies)
for(thirdCiv in getCommonKnownCivs()
for (thirdCiv in getCommonKnownCivs()
.filter { it.getDiplomacyManager(civInfo).hasFlag(DiplomacyFlags.DeclarationOfFriendship) }) {
val otherCivRelationshipWithThirdCiv = otherCiv().getDiplomacyManager(thirdCiv).relationshipLevel()
when (otherCivRelationshipWithThirdCiv) {
@ -628,11 +641,11 @@ class DiplomacyManager() {
}
}
fun denounce(){
setModifier(DiplomaticModifiers.Denunciation,-35f)
otherCivDiplomacy().setModifier(DiplomaticModifiers.Denunciation,-35f)
setFlag(DiplomacyFlags.Denunceation,30)
otherCivDiplomacy().setFlag(DiplomacyFlags.Denunceation,30)
fun denounce() {
setModifier(DiplomaticModifiers.Denunciation, -35f)
otherCivDiplomacy().setModifier(DiplomaticModifiers.Denunciation, -35f)
setFlag(DiplomacyFlags.Denunceation, 30)
otherCivDiplomacy().setFlag(DiplomacyFlags.Denunceation, 30)
otherCiv().addNotification("[${civInfo.civName}] has denounced us!", Color.RED)
@ -640,28 +653,28 @@ class DiplomacyManager() {
getCommonKnownCivs().filter { it.isMajorCiv() }.forEach { thirdCiv ->
thirdCiv.addNotification("[${civInfo.civName}] has denounced [${otherCiv().civName}]!", null, Color.RED)
val thirdCivRelationshipWithOtherCiv = thirdCiv.getDiplomacyManager(otherCiv()).relationshipLevel()
when(thirdCivRelationshipWithOtherCiv){
RelationshipLevel.Unforgivable -> addModifier(DiplomaticModifiers.DenouncedOurEnemies,15f)
RelationshipLevel.Enemy -> addModifier(DiplomaticModifiers.DenouncedOurEnemies,5f)
RelationshipLevel.Friend -> addModifier(DiplomaticModifiers.DenouncedOurAllies,-5f)
RelationshipLevel.Ally -> addModifier(DiplomaticModifiers.DenouncedOurAllies,-15f)
when (thirdCivRelationshipWithOtherCiv) {
RelationshipLevel.Unforgivable -> addModifier(DiplomaticModifiers.DenouncedOurEnemies, 15f)
RelationshipLevel.Enemy -> addModifier(DiplomaticModifiers.DenouncedOurEnemies, 5f)
RelationshipLevel.Friend -> addModifier(DiplomaticModifiers.DenouncedOurAllies, -5f)
RelationshipLevel.Ally -> addModifier(DiplomaticModifiers.DenouncedOurAllies, -15f)
}
}
}
fun agreeNotToSettleNear(){
otherCivDiplomacy().setFlag(DiplomacyFlags.AgreedToNotSettleNearUs,100)
addModifier(DiplomaticModifiers.UnacceptableDemands,-10f)
fun agreeNotToSettleNear() {
otherCivDiplomacy().setFlag(DiplomacyFlags.AgreedToNotSettleNearUs, 100)
addModifier(DiplomaticModifiers.UnacceptableDemands, -10f)
otherCiv().addNotification("[${civInfo.civName}] agreed to stop settling cities near us!", Color.MAROON)
}
fun refuseDemandNotToSettleNear(){
addModifier(DiplomaticModifiers.UnacceptableDemands,-20f)
otherCivDiplomacy().setFlag(DiplomacyFlags.IgnoreThemSettlingNearUs,100)
otherCivDiplomacy().addModifier(DiplomaticModifiers.RefusedToNotSettleCitiesNearUs,-15f)
fun refuseDemandNotToSettleNear() {
addModifier(DiplomaticModifiers.UnacceptableDemands, -20f)
otherCivDiplomacy().setFlag(DiplomacyFlags.IgnoreThemSettlingNearUs, 100)
otherCivDiplomacy().addModifier(DiplomaticModifiers.RefusedToNotSettleCitiesNearUs, -15f)
otherCiv().addNotification("[${civInfo.civName}] refused to stop settling cities near us!", Color.MAROON)
}
//endregion
}
}

View File

@ -7,6 +7,7 @@ import com.unciv.UncivGame
import com.unciv.logic.automation.UnitAutomation
import com.unciv.logic.automation.WorkerAutomation
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.NotificationType
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.Unique
import com.unciv.models.ruleset.unit.BaseUnit
@ -615,7 +616,7 @@ class MapUnit {
val city = civInfo.cities.random(tileBasedRandom)
city.population.population++
city.population.autoAssignPopulation()
civInfo.addNotification("We have found survivors in the ruins - population added to [" + city.name + "]", tile.position, Color.GREEN)
civInfo.addNotification("We have found survivors in the ruins - population added to [" + city.name + "]", tile.position, NotificationType.Growth)
}
val researchableAncientEraTechs = tile.tileMap.gameInfo.ruleSet.technologies.values
.filter {
@ -627,7 +628,7 @@ class MapUnit {
actions.add {
val tech = researchableAncientEraTechs.random(tileBasedRandom).name
civInfo.tech.addTechnology(tech)
civInfo.addNotification("We have discovered the lost technology of [$tech] in the ruins!", tile.position, Color.BLUE)
civInfo.addNotification("We have discovered the lost technology of [$tech] in the ruins!", tile.position, NotificationType.Science)
}
@ -656,7 +657,7 @@ class MapUnit {
actions.add {
civInfo.policies.addCulture(20)
civInfo.addNotification("We have discovered cultural artifacts in the ruins! (+20 Culture)", tile.position, Color.GOLD)
civInfo.addNotification("We have discovered cultural artifacts in the ruins! (+20 Culture)", tile.position, NotificationType.Culture)
}
// Map of the surrounding area

View File

@ -12,7 +12,7 @@ import kotlin.math.min
class NotificationsScroll(internal val worldScreen: WorldScreen) : ScrollPane(null) {
var notificationsHash : Int = 0
var notificationsHash: Int = 0
private var notificationsTable = Table()
@ -24,17 +24,19 @@ class NotificationsScroll(internal val worldScreen: WorldScreen) : ScrollPane(nu
internal fun update(notifications: MutableList<Notification>) {
// no news? - keep our list as it is, especially don't reset scroll position
if(notificationsHash == notifications.hashCode())
if (notificationsHash == notifications.hashCode())
return
notificationsHash = notifications.hashCode()
notificationsTable.clearChildren()
for (notification in notifications.toList().reversed()) { // toList to avoid concurrency problems
val label = notification.text.toLabel(Color.BLACK,30)
val label = notification.text.toLabel(Color.BLACK, 30)
val listItem = Table()
listItem.add(ImageGetter.getCircle()
.apply { color=notification.color }).size(20f).padRight(5f)
if (notification.notificationType != null)
listItem.add(ImageGetter.getImage("NotificationIcons/" + notification.notificationType!!.name)).size(20f).padRight(5f)
else listItem.add(ImageGetter.getCircle()
.apply { color = notification.color }).size(20f).padRight(5f)
listItem.background = ImageGetter.getRoundedEdgeTableBackground().apply { setScale(0.5f) }
listItem.add(label)
@ -52,7 +54,7 @@ class NotificationsScroll(internal val worldScreen: WorldScreen) : ScrollPane(nu
}
notificationsTable.pack()
pack()
height = min(notificationsTable.height,worldScreen.stage.height * 2 / 3 - 15f)
height = min(notificationsTable.height, worldScreen.stage.height * 2 / 3 - 15f)
}
}
}