Add Notifications Log (#7122)

This commit is contained in:
alexban011
2022-06-25 14:40:42 +03:00
committed by GitHub
parent 50a8ff3ce0
commit 8047278d80
9 changed files with 150 additions and 15 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -704,6 +704,7 @@ Continuous rendering =
When disabled, saves battery life but certain animations will be suspended = When disabled, saves battery life but certain animations will be suspended =
Order trade offers by amount = Order trade offers by amount =
Ask for confirmation when pressing next turn = Ask for confirmation when pressing next turn =
Notifications log max turns =
Check extension mods based on: = Check extension mods based on: =
-none- = -none- =
Reload mods = Reload mods =
@ -1124,6 +1125,7 @@ City-State Luxuries =
Occupied City = Occupied City =
Buildings = Buildings =
Wonders = Wonders =
Notifications =
Base values = Base values =
Bonuses = Bonuses =
Final = Final =
@ -1166,6 +1168,8 @@ Near [city] =
Somewhere around [city] = Somewhere around [city] =
Far away = Far away =
Status = Status =
Current turn =
Turn [turnNumber] =
Location = Location =
Unimproved = Unimproved =
Number of tiles with this resource\nin your territory, without an\nappropriate improvement to use it = Number of tiles with this resource\nin your territory, without an\nappropriate improvement to use it =

View File

@ -158,11 +158,17 @@ class CivilizationInfo {
var ruinsManager = RuinsManager() var ruinsManager = RuinsManager()
var diplomacy = HashMap<String, DiplomacyManager>() var diplomacy = HashMap<String, DiplomacyManager>()
var proximity = HashMap<String, Proximity>() var proximity = HashMap<String, Proximity>()
var notifications = ArrayList<Notification>()
val popupAlerts = ArrayList<PopupAlert>() val popupAlerts = ArrayList<PopupAlert>()
private var allyCivName: String? = null private var allyCivName: String? = null
var naturalWonders = ArrayList<String>() var naturalWonders = ArrayList<String>()
var notifications = ArrayList<Notification>()
var notificationsLog = ArrayList<NotificationsLog>()
class NotificationsLog(val turn: Int = 0) {
var notifications = ArrayList<Notification>()
}
/** for trades here, ourOffers is the current civ's offers, and theirOffers is what the requesting civ offers */ /** for trades here, ourOffers is the current civ's offers, and theirOffers is what the requesting civ offers */
val tradeRequests = ArrayList<TradeRequest>() val tradeRequests = ArrayList<TradeRequest>()
@ -267,6 +273,7 @@ class CivilizationInfo {
toReturn.exploredTiles.addAll(gameInfo.tileMap.values.asSequence().map { it.position }.filter { it in exploredTiles }) toReturn.exploredTiles.addAll(gameInfo.tileMap.values.asSequence().map { it.position }.filter { it in exploredTiles })
toReturn.lastSeenImprovement.putAll(lastSeenImprovement) toReturn.lastSeenImprovement.putAll(lastSeenImprovement)
toReturn.notifications.addAll(notifications) toReturn.notifications.addAll(notifications)
toReturn.notificationsLog.addAll(notificationsLog)
toReturn.citiesCreated = citiesCreated toReturn.citiesCreated = citiesCreated
toReturn.popupAlerts.addAll(popupAlerts) toReturn.popupAlerts.addAll(popupAlerts)
toReturn.tradeRequests.addAll(tradeRequests) toReturn.tradeRequests.addAll(tradeRequests)
@ -912,6 +919,16 @@ class CivilizationInfo {
} }
fun endTurn() { fun endTurn() {
val notificationsThisTurn = NotificationsLog(gameInfo.turns)
notificationsThisTurn.notifications.addAll(notifications)
while (notificationsLog.size >= UncivGame.Current.settings.notificationsLogMaxTurns) {
notificationsLog.removeFirst()
}
if (notificationsThisTurn.notifications.isNotEmpty())
notificationsLog.add(notificationsThisTurn)
notifications.clear() notifications.clear()
updateStatsForNextTurn() updateStatsForNextTurn()
val nextTurnStats = statsForNextTurn val nextTurnStats = statsForNextTurn

View File

@ -1,7 +1,11 @@
package com.unciv.logic.civilization package com.unciv.logic.civilization
import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.models.ruleset.Ruleset
import com.unciv.ui.cityscreen.CityScreen import com.unciv.ui.cityscreen.CityScreen
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.pickerscreens.TechPickerScreen import com.unciv.ui.pickerscreens.TechPickerScreen
import com.unciv.ui.trade.DiplomacyScreen import com.unciv.ui.trade.DiplomacyScreen
import com.unciv.ui.utils.MayaCalendar import com.unciv.ui.utils.MayaCalendar
@ -48,6 +52,22 @@ open class Notification() {
this.icons = notificationIcons this.icons = notificationIcons
this.action = action this.action = action
} }
fun addNotificationIcons(ruleset: Ruleset, iconSize: Float, table: Table) {
if (icons.isEmpty()) return
for (icon in icons.reversed()) {
val image: Actor = when {
ruleset.technologies.containsKey(icon) -> ImageGetter.getTechIcon(icon)
ruleset.nations.containsKey(icon) -> ImageGetter.getNationIndicator(
ruleset.nations[icon]!!,
iconSize
)
ruleset.units.containsKey(icon) -> ImageGetter.getUnitIcon(icon)
else -> ImageGetter.getImage(icon)
}
table.add(image).size(iconSize).padRight(5f)
}
}
} }
/** defines what to do if the user clicks on a notification */ /** defines what to do if the user clicks on a notification */

View File

@ -56,6 +56,8 @@ class GameSettings {
var useDemographics: Boolean = false var useDemographics: Boolean = false
var showZoomButtons: Boolean = false var showZoomButtons: Boolean = false
var notificationsLogMaxTurns = 5
var androidCutout: Boolean = false var androidCutout: Boolean = false
var multiplayer = GameSettingsMultiplayer() var multiplayer = GameSettingsMultiplayer()

View File

@ -3,7 +3,10 @@ package com.unciv.ui.options
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.civilization.PlayerType import com.unciv.logic.civilization.PlayerType
import com.unciv.models.metadata.GameSettings
import com.unciv.ui.utils.BaseScreen import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.UncivSlider
import com.unciv.ui.utils.extensions.toLabel
import com.unciv.ui.worldscreen.WorldScreen import com.unciv.ui.worldscreen.WorldScreen
fun gameplayTab( fun gameplayTab(
@ -35,4 +38,20 @@ fun gameplayTab(
) { settings.automatedWorkersReplaceImprovements = it } ) { settings.automatedWorkersReplaceImprovements = it }
optionsPopup.addCheckbox(this, "Order trade offers by amount", settings.orderTradeOffersByAmount) { settings.orderTradeOffersByAmount = it } optionsPopup.addCheckbox(this, "Order trade offers by amount", settings.orderTradeOffersByAmount) { settings.orderTradeOffersByAmount = it }
optionsPopup.addCheckbox(this, "Ask for confirmation when pressing next turn", settings.confirmNextTurn) { settings.confirmNextTurn = it } optionsPopup.addCheckbox(this, "Ask for confirmation when pressing next turn", settings.confirmNextTurn) { settings.confirmNextTurn = it }
addNotificationLogMaxTurnsSlider(this, settings, UncivGame.Current.worldScreen, optionsPopup.selectBoxMinWidth)
}
private fun addNotificationLogMaxTurnsSlider(table: Table, settings: GameSettings, screen: BaseScreen?, selectBoxMinWidth: Float) {
table.add("Notifications log max turns".toLabel()).left().fillX()
val minimapSlider = UncivSlider(
3f, 15f, 1f,
initial = settings.notificationsLogMaxTurns.toFloat()
) {
val turns = it.toInt()
settings.notificationsLogMaxTurns = turns
settings.save()
}
table.add(minimapSlider).minWidth(selectBoxMinWidth).pad(10f).row()
} }

View File

@ -1,6 +1,7 @@
package com.unciv.ui.overviewscreen package com.unciv.ui.overviewscreen
import com.badlogic.gdx.utils.Align import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.ui.utils.KeyCharAndCode import com.unciv.ui.utils.KeyCharAndCode
import com.unciv.ui.overviewscreen.EmpireOverviewTab.EmpireOverviewTabPersistableData import com.unciv.ui.overviewscreen.EmpireOverviewTab.EmpireOverviewTabPersistableData
@ -59,7 +60,10 @@ enum class EmpireOverviewCategories(
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, _: EmpireOverviewTabPersistableData?) fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, _: EmpireOverviewTabPersistableData?)
= WonderOverviewTab(viewingPlayer, overviewScreen), = WonderOverviewTab(viewingPlayer, overviewScreen),
fun (viewingPlayer: CivilizationInfo) = (viewingPlayer.naturalWonders.isEmpty() && viewingPlayer.cities.isEmpty()).toState()), fun (viewingPlayer: CivilizationInfo) = (viewingPlayer.naturalWonders.isEmpty() && viewingPlayer.cities.isEmpty()).toState()),
; Notifications("OtherIcons/Notifications", 'N', Align.top,
fun (viewingPlayer: CivilizationInfo, overviewScreen: EmpireOverviewScreen, _: EmpireOverviewTabPersistableData?)
= NotificationsOverviewTable(worldScreen = UncivGame.Current.worldScreen!!, viewingPlayer, overviewScreen),
fun (_: CivilizationInfo) = EmpireOverviewTabState.Normal);
constructor(iconName: String, shortcutChar: Char, scrollAlign: Int, factory: FactoryType, stateTester: StateTesterType = { _ -> EmpireOverviewTabState.Normal }) constructor(iconName: String, shortcutChar: Char, scrollAlign: Int, factory: FactoryType, stateTester: StateTesterType = { _ -> EmpireOverviewTabState.Normal })
: this(iconName, KeyCharAndCode(shortcutChar), scrollAlign, factory, stateTester) : this(iconName, KeyCharAndCode(shortcutChar), scrollAlign, factory, stateTester)

View File

@ -0,0 +1,80 @@
package com.unciv.ui.overviewscreen
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.UncivGame
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.civilization.Notification
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.WrappableLabel
import com.unciv.ui.utils.extensions.onClick
import com.unciv.ui.worldscreen.WorldScreen
class NotificationsOverviewTable(
val worldScreen: WorldScreen,
viewingPlayer: CivilizationInfo,
overviewScreen: EmpireOverviewScreen
) : EmpireOverviewTab(viewingPlayer, overviewScreen) {
val notificationLog = viewingPlayer.notificationsLog
private val notificationTable = Table(BaseScreen.skin)
val scaleFactor = 0.3f
val inverseScaleFactor = 1f / scaleFactor
private val maxWidthOfStage = 0.333f
private val maxEntryWidth = worldScreen.stage.width * maxWidthOfStage * inverseScaleFactor
val iconSize = 20f
init {
val tablePadding = 30f
defaults().pad(tablePadding).top()
generateNotificationTable()
add(notificationTable)
}
private fun generateNotificationTable() {
if (viewingPlayer.notifications.isNotEmpty())
notificationTable.add(notificationsArrayTable("Current", viewingPlayer.notifications)).row()
for (notification in notificationLog.asReversed()) {
notificationTable.add(notificationsArrayTable(notification.turn.toString(), notification.notifications))
notificationTable.padTop(20f).row()
}
}
private fun notificationsArrayTable(index: String, notifications: ArrayList<Notification>): Table {
val turnTable = Table(BaseScreen.skin)
if (index != "Current")
turnTable.add("Turn [$index]").row()
else
turnTable.add("Current turn").row()
for (notification in notifications) {
val notificationTable = Table(BaseScreen.skin)
val labelWidth = maxEntryWidth * notification.icons.size - 10f
val label = WrappableLabel(notification.text, labelWidth, Color.BLACK, 20)
notificationTable.add(label)
notificationTable.background = ImageGetter.getRoundedEdgeRectangle()
notificationTable.touchable = Touchable.enabled
notificationTable.onClick {
UncivGame.Current.resetToWorldScreen()
notification.action?.execute(worldScreen)
}
notification.addNotificationIcons(worldScreen.gameInfo.ruleSet, iconSize, notificationTable)
turnTable.add(notificationTable).padTop(5f)
turnTable.padTop(20f).row()
}
turnTable.padTop(20f).row()
return turnTable
}
}

View File

@ -78,18 +78,7 @@ class NotificationsScroll(
listItem.add(label).padRight(10f) listItem.add(label).padRight(10f)
} }
if (notification.icons.isNotEmpty()) { notification.addNotificationIcons(worldScreen.gameInfo.ruleSet, iconSize, listItem)
val ruleset = worldScreen.gameInfo.ruleSet
for (icon in notification.icons.reversed()) {
val image: Actor = when {
ruleset.technologies.containsKey(icon) -> ImageGetter.getTechIcon(icon)
ruleset.nations.containsKey(icon) -> ImageGetter.getNationIndicator(ruleset.nations[icon]!!, iconSize)
ruleset.units.containsKey(icon) -> ImageGetter.getUnitIcon(icon)
else -> ImageGetter.getImage(icon)
}
listItem.add(image).size(iconSize).padRight(5f)
}
}
// using a large click area with no gap in between each message item. // using a large click area with no gap in between each message item.
// this avoids accidentally clicking in between the messages, resulting in a map click // this avoids accidentally clicking in between the messages, resulting in a map click