mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-26 13:27:22 -04:00
Add multiplayer turn sound notification (#6995)
* Refactor: Extract methods & reduce code duplication * Refactor: Rename Sounds to SoundPlayer * Refactor: Make UncivSound a data class As far as I can see, UncivSoundConstants served no purpose * Refactor: Reorder sounds * Refactor: Split up ExtensionFunctions and move into own package * Add multiplayer turn sound notification * Refactor: Remove unnecessary double translation * Refactor: Reduce code duplication * Refactor: No if for boolean logic
This commit is contained in:
parent
9918353c66
commit
3e6fc0e22a
@ -602,12 +602,16 @@ Resign =
|
||||
Are you sure you want to resign? =
|
||||
You can only resign if it's your turn =
|
||||
[civName] resigned and is now controlled by AI =
|
||||
Last refresh: [time] [timeUnit] ago =
|
||||
Current Turn: [civName] since [time] [timeUnit] ago =
|
||||
Last refresh: [duration] ago =
|
||||
Current Turn: [civName] since [duration] ago =
|
||||
Seconds =
|
||||
Minutes =
|
||||
Hours =
|
||||
Days =
|
||||
[amount] Seconds =
|
||||
[amount] Minutes =
|
||||
[amount] Hours =
|
||||
[amount] Days =
|
||||
Server limit reached! Please wait for [time] seconds =
|
||||
File could not be found on the multiplayer server =
|
||||
Unhandled problem, [errorMessage] =
|
||||
@ -1395,7 +1399,7 @@ Doing this will reset your current user ID to the clipboard contents - are you s
|
||||
ID successfully set! =
|
||||
Invalid ID! =
|
||||
|
||||
# Multiplayer options menu
|
||||
# Multiplayer options tab
|
||||
|
||||
Enable multiplayer status button in singleplayer games =
|
||||
Update status of currently played game every: =
|
||||
@ -1406,7 +1410,12 @@ Check connection to server =
|
||||
Awaiting response... =
|
||||
Success! =
|
||||
Failed! =
|
||||
|
||||
Sound notification for when it's your turn in your currently open game: =
|
||||
Sound notification for when it's your turn in any other game: =
|
||||
Notification [number] =
|
||||
Chimes =
|
||||
Choir =
|
||||
[unit] Attack Sound =
|
||||
|
||||
# Mods
|
||||
|
||||
|
BIN
android/assets/sounds/notification1.mp3
Normal file
BIN
android/assets/sounds/notification1.mp3
Normal file
Binary file not shown.
BIN
android/assets/sounds/notification2.mp3
Normal file
BIN
android/assets/sounds/notification2.mp3
Normal file
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
package com.unciv
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
@ -14,22 +14,35 @@ import com.unciv.logic.map.MapSizeNew
|
||||
import com.unciv.logic.map.MapType
|
||||
import com.unciv.logic.map.mapgenerator.MapGenerator
|
||||
import com.unciv.models.metadata.BaseRuleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.ui.multiplayer.MultiplayerScreen
|
||||
import com.unciv.ui.mapeditor.*
|
||||
import com.unciv.models.metadata.GameSetupInfo
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.mapeditor.EditorMapHolder
|
||||
import com.unciv.ui.mapeditor.MapEditorScreen
|
||||
import com.unciv.ui.multiplayer.MultiplayerScreen
|
||||
import com.unciv.ui.map.TileGroupMap
|
||||
import com.unciv.ui.newgamescreen.NewGameScreen
|
||||
import com.unciv.ui.pickerscreens.ModManagementScreen
|
||||
import com.unciv.ui.popup.*
|
||||
import com.unciv.ui.popup.ExitGamePopup
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.popup.closeAllPopups
|
||||
import com.unciv.ui.popup.hasOpenPopups
|
||||
import com.unciv.ui.popup.popups
|
||||
import com.unciv.ui.saves.LoadGameScreen
|
||||
import com.unciv.ui.saves.QuickSave
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.AutoScrollPane
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
||||
import com.unciv.ui.utils.extensions.center
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.setFontSize
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.worldscreen.mainmenu.WorldScreenMenuPopup
|
||||
import kotlin.math.min
|
||||
|
||||
|
@ -9,18 +9,16 @@ import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.GameSaver
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.multiplayer.OnlineMultiplayer
|
||||
import com.unciv.models.metadata.GameSettings
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.tilesets.TileSetCache
|
||||
import com.unciv.models.translations.Translations
|
||||
import com.unciv.ui.LanguagePickerScreen
|
||||
import com.unciv.ui.audio.GameSounds
|
||||
import com.unciv.ui.audio.MusicController
|
||||
import com.unciv.ui.audio.MusicMood
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.worldscreen.PlayerReadyScreen
|
||||
import com.unciv.ui.worldscreen.WorldScreen
|
||||
import com.unciv.logic.multiplayer.OnlineMultiplayer
|
||||
import com.unciv.ui.LanguagePickerScreen
|
||||
import com.unciv.ui.audio.Sounds
|
||||
import com.unciv.ui.audio.SoundPlayer
|
||||
import com.unciv.ui.crashhandling.closeExecutors
|
||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
@ -28,6 +26,11 @@ import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.multiplayer.LoadDeepLinkScreen
|
||||
import com.unciv.ui.multiplayer.MultiplayerHelpers
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.extensions.center
|
||||
import com.unciv.ui.crashhandling.wrapCrashHandlingUnit
|
||||
import com.unciv.ui.worldscreen.PlayerReadyScreen
|
||||
import com.unciv.ui.worldscreen.WorldScreen
|
||||
import com.unciv.utils.debug
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.util.*
|
||||
@ -103,6 +106,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
||||
*/
|
||||
settings = gameSaver.getGeneralSettings() // needed for the screen
|
||||
screen = LoadingScreen() // NOT dependent on any atlas or skin
|
||||
GameSounds.init()
|
||||
musicController = MusicController() // early, but at this point does only copy volume from settings
|
||||
audioExceptionHelper?.installHooks(
|
||||
musicController.getAudioLoopCallback(),
|
||||
@ -194,23 +198,25 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
||||
}
|
||||
|
||||
private fun tryLoadDeepLinkedGame() = launchCrashHandling("LoadDeepLinkedGame") {
|
||||
if (deepLinkedMultiplayerGame != null) {
|
||||
if (deepLinkedMultiplayerGame == null) return@launchCrashHandling
|
||||
|
||||
postCrashHandlingRunnable {
|
||||
setScreen(LoadDeepLinkScreen())
|
||||
}
|
||||
try {
|
||||
onlineMultiplayer.loadGame(deepLinkedMultiplayerGame!!)
|
||||
} catch (ex: Exception) {
|
||||
postCrashHandlingRunnable {
|
||||
setScreen(LoadDeepLinkScreen())
|
||||
}
|
||||
try {
|
||||
onlineMultiplayer.loadGame(deepLinkedMultiplayerGame!!)
|
||||
} catch (ex: Exception) {
|
||||
postCrashHandlingRunnable {
|
||||
val mainMenu = MainMenuScreen()
|
||||
setScreen(mainMenu)
|
||||
val popup = Popup(mainMenu)
|
||||
popup.addGoodSizedLabel(MultiplayerHelpers.getLoadExceptionMessage(ex))
|
||||
popup.row()
|
||||
popup.addCloseButton()
|
||||
popup.open()
|
||||
}
|
||||
val mainMenu = MainMenuScreen()
|
||||
setScreen(mainMenu)
|
||||
val popup = Popup(mainMenu)
|
||||
popup.addGoodSizedLabel(MultiplayerHelpers.getLoadExceptionMessage(ex))
|
||||
popup.row()
|
||||
popup.addCloseButton()
|
||||
popup.open()
|
||||
}
|
||||
} finally {
|
||||
deepLinkedMultiplayerGame = null
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,7 +248,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
||||
Gdx.input.inputProcessor = null // don't allow ANRs when shutting down, that's silly
|
||||
|
||||
cancelDiscordEvent?.invoke()
|
||||
Sounds.clearCache()
|
||||
SoundPlayer.clearCache()
|
||||
if (::musicController.isInitialized) musicController.gracefulShutdown() // Do allow fade-out
|
||||
closeExecutors()
|
||||
|
||||
@ -274,6 +280,8 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
||||
companion object {
|
||||
lateinit var Current: UncivGame
|
||||
fun isCurrentInitialized() = this::Current.isInitialized
|
||||
fun isCurrentGame(gameId: String): Boolean = isCurrentInitialized() && Current.isGameInfoInitialized() && Current.gameInfo.gameId == gameId
|
||||
fun isDeepLinkedGameLoading() = isCurrentInitialized() && Current.deepLinkedMultiplayerGame != null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.models.metadata.GameSpeed
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.randomWeighted
|
||||
import com.unciv.ui.utils.extensions.randomWeighted
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
@ -3,9 +3,13 @@ package com.unciv.logic.battle
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.utils.debug
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.civilization.*
|
||||
import com.unciv.logic.civilization.AlertType
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.LocationAction
|
||||
import com.unciv.logic.civilization.NotificationIcon
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.civilization.PopupAlert
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
@ -18,7 +22,8 @@ import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import com.unciv.utils.debug
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
@ -8,7 +8,7 @@ import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import java.util.*
|
||||
import kotlin.collections.set
|
||||
import kotlin.math.max
|
||||
|
@ -7,7 +7,7 @@ import com.unciv.models.UncivSound
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.UnitType
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -54,14 +54,14 @@ class CityCombatant(val city: CityInfo) : ICombatant {
|
||||
// The way all of this adds up...
|
||||
// All ancient techs - 0.5 extra, Classical - 2.7, Medieval - 8, Renaissance - 17.5,
|
||||
// Industrial - 32.4, Modern - 51, Atomic - 72.5, All - 118.3
|
||||
|
||||
|
||||
// Garrisoned unit gives up to 20% of strength to city, health-dependant
|
||||
if (cityTile.militaryUnit != null)
|
||||
strength += cityTile.militaryUnit!!.baseUnit().strength * (cityTile.militaryUnit!!.health / 100f) * modConstants.cityStrengthFromGarrison
|
||||
|
||||
var buildingsStrength = city.cityConstructions.getBuiltBuildings().sumOf { it.cityStrength }.toFloat()
|
||||
val stateForConditionals = StateForConditionals(getCivInfo(), city, ourCombatant = this, combatAction = combatAction)
|
||||
|
||||
|
||||
for (unique in getCivInfo().getMatchingUniques(UniqueType.BetterDefensiveBuildings, stateForConditionals))
|
||||
buildingsStrength *= unique.params[0].toPercent()
|
||||
strength += buildingsStrength
|
||||
@ -70,4 +70,4 @@ class CityCombatant(val city: CityInfo) : ICombatant {
|
||||
}
|
||||
|
||||
override fun toString() = city.name // for debug
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
||||
override fun isInvisible(to: CivilizationInfo): Boolean = unit.isInvisible(to)
|
||||
override fun canAttack(): Boolean = unit.canAttack()
|
||||
override fun matchesCategory(category: String) = unit.matchesFilter(category)
|
||||
override fun getAttackSound() = unit.baseUnit.attackSound.let {
|
||||
if (it==null) UncivSound.Click else UncivSound.custom(it)
|
||||
override fun getAttackSound() = unit.baseUnit.attackSound.let {
|
||||
if (it == null) UncivSound.Click else UncivSound(it)
|
||||
}
|
||||
|
||||
override fun takeDamage(damage: Int) {
|
||||
@ -50,10 +50,10 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
||||
return unit.name+" of "+unit.civInfo.civName
|
||||
}
|
||||
|
||||
fun getMatchingUniques(uniqueType: UniqueType, conditionalState: StateForConditionals, checkCivUniques: Boolean): Sequence<Unique> =
|
||||
fun getMatchingUniques(uniqueType: UniqueType, conditionalState: StateForConditionals, checkCivUniques: Boolean): Sequence<Unique> =
|
||||
unit.getMatchingUniques(uniqueType, conditionalState, checkCivUniques)
|
||||
|
||||
fun hasUnique(uniqueType: UniqueType, conditionalState: StateForConditionals? = null): Boolean =
|
||||
if (conditionalState == null) unit.hasUnique(uniqueType)
|
||||
else unit.hasUnique(uniqueType, conditionalState)
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import com.unciv.logic.automation.ConstructionAutomation
|
||||
import com.unciv.logic.civilization.AlertType
|
||||
import com.unciv.logic.civilization.NotificationIcon
|
||||
import com.unciv.logic.civilization.PopupAlert
|
||||
import com.unciv.logic.map.MapUnit // for Kdoc only
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
@ -21,11 +21,9 @@ import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.CivilopediaCategories
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.withItem
|
||||
import com.unciv.ui.utils.withoutItem
|
||||
import com.unciv.ui.worldscreen.unit.UnitActions // for Kdoc only
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import com.unciv.ui.utils.extensions.withItem
|
||||
import com.unciv.ui.utils.extensions.withoutItem
|
||||
import com.unciv.ui.worldscreen.unit.UnitActions
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
@ -7,9 +7,9 @@ import com.unciv.logic.civilization.NotificationIcon
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.withItem
|
||||
import com.unciv.ui.utils.withoutItem
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import com.unciv.ui.utils.extensions.withItem
|
||||
import com.unciv.ui.utils.extensions.withoutItem
|
||||
import kotlin.math.max
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
@ -64,18 +64,18 @@ class CityExpansionManager {
|
||||
val baseCost = 50
|
||||
val distanceFromCenter = tileInfo.aerialDistanceTo(cityInfo.getCenterTile())
|
||||
var cost = baseCost * (distanceFromCenter - 1) + tilesClaimed() * 5.0
|
||||
|
||||
|
||||
for (unique in cityInfo.getMatchingUniques(UniqueType.TileCostPercentage)) {
|
||||
if (cityInfo.matchesFilter(unique.params[1]))
|
||||
cost *= unique.params[0].toPercent()
|
||||
}
|
||||
|
||||
|
||||
return cost.roundToInt()
|
||||
}
|
||||
|
||||
fun getChoosableTiles() = cityInfo.getCenterTile().getTilesInDistance(5)
|
||||
.filter { it.getOwner() == null }
|
||||
|
||||
|
||||
fun chooseNewTileToOwn(): TileInfo? {
|
||||
// Technically, in the original a random tile with the lowest score was selected
|
||||
// However, doing this requires either caching it, which is way more work,
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.utils.debug
|
||||
import com.unciv.logic.battle.Battle
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.NotificationIcon
|
||||
@ -12,7 +11,8 @@ import com.unciv.logic.trade.TradeLogic
|
||||
import com.unciv.logic.trade.TradeOffer
|
||||
import com.unciv.logic.trade.TradeType
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.withoutItem
|
||||
import com.unciv.ui.utils.extensions.withoutItem
|
||||
import com.unciv.utils.debug
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
@ -7,13 +7,13 @@ import com.unciv.models.Religion
|
||||
import com.unciv.models.metadata.GameSpeed
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
|
||||
class CityInfoReligionManager {
|
||||
@Transient
|
||||
lateinit var cityInfo: CityInfo
|
||||
|
||||
// This needs to be kept track of for the
|
||||
|
||||
// This needs to be kept track of for the
|
||||
// "[Stats] when a city adopts this religion for the first time" unique
|
||||
val religionsAtSomePointAdopted: HashSet<String> = hashSetOf()
|
||||
|
||||
@ -21,7 +21,7 @@ class CityInfoReligionManager {
|
||||
// Cached because using `updateNumberOfFollowers` to get this value resulted in many calls
|
||||
@Transient
|
||||
private val followers: Counter<String> = Counter()
|
||||
|
||||
|
||||
@delegate:Transient
|
||||
private val pressureFromAdjacentCities: Int by lazy {
|
||||
when (cityInfo.civInfo.gameInfo.gameParameters.gameSpeed) {
|
||||
@ -31,13 +31,13 @@ class CityInfoReligionManager {
|
||||
GameSpeed.Marathon -> 2
|
||||
}
|
||||
}
|
||||
|
||||
var religionThisIsTheHolyCityOf: String? = null
|
||||
|
||||
|
||||
var religionThisIsTheHolyCityOf: String? = null
|
||||
|
||||
init {
|
||||
clearAllPressures()
|
||||
}
|
||||
|
||||
|
||||
fun clone(): CityInfoReligionManager {
|
||||
val toReturn = CityInfoReligionManager()
|
||||
toReturn.cityInfo = cityInfo
|
||||
@ -47,7 +47,7 @@ class CityInfoReligionManager {
|
||||
toReturn.religionThisIsTheHolyCityOf = religionThisIsTheHolyCityOf
|
||||
return toReturn
|
||||
}
|
||||
|
||||
|
||||
fun setTransients(cityInfo: CityInfo) {
|
||||
this.cityInfo = cityInfo
|
||||
// We don't need to check for changes in the majority religion, and as this
|
||||
@ -55,33 +55,33 @@ class CityInfoReligionManager {
|
||||
// have any effect
|
||||
updateNumberOfFollowers(false)
|
||||
}
|
||||
|
||||
|
||||
fun endTurn() {
|
||||
getAffectedBySurroundingCities()
|
||||
}
|
||||
|
||||
|
||||
fun getUniques(): Sequence<Unique> {
|
||||
val majorityReligion = getMajorityReligion() ?: return sequenceOf()
|
||||
return majorityReligion.getFollowerUniques()
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun getPressures(): Counter<String> = pressures.clone()
|
||||
|
||||
|
||||
private fun clearAllPressures() {
|
||||
pressures.clear()
|
||||
// We add pressure for following no religion
|
||||
// Basically used as a failsafe so that there is always some religion,
|
||||
// Basically used as a failsafe so that there is always some religion,
|
||||
// and we don't suddenly divide by 0 somewhere
|
||||
// Should be removed when updating the followers so it never becomes the majority religion,
|
||||
// Should be removed when updating the followers so it never becomes the majority religion,
|
||||
// `null` is used for that instead.
|
||||
pressures.add(Constants.noReligionName, 100)
|
||||
}
|
||||
|
||||
|
||||
fun addPressure(religionName: String, amount: Int, shouldUpdateFollowers: Boolean = true) {
|
||||
if (!cityInfo.civInfo.gameInfo.isReligionEnabled()) return // No religion, no pressures
|
||||
pressures.add(religionName, amount)
|
||||
|
||||
|
||||
if (shouldUpdateFollowers) {
|
||||
updateNumberOfFollowers(shouldUpdateFollowers)
|
||||
}
|
||||
@ -96,12 +96,12 @@ class CityInfoReligionManager {
|
||||
if (pressureFromAtheism != null) pressures[Constants.noReligionName] = pressureFromAtheism
|
||||
updateNumberOfFollowers()
|
||||
}
|
||||
|
||||
|
||||
fun updatePressureOnPopulationChange(populationChangeAmount: Int) {
|
||||
val majorityReligion =
|
||||
if (getMajorityReligionName() != null) getMajorityReligionName()!!
|
||||
else Constants.noReligionName
|
||||
|
||||
|
||||
if (populationChangeAmount > 0) {
|
||||
addPressure(majorityReligion, 100 * populationChangeAmount)
|
||||
} else {
|
||||
@ -112,18 +112,18 @@ class CityInfoReligionManager {
|
||||
private fun triggerReligionAdoption(newMajorityReligion: String) {
|
||||
val newMajorityReligionObject = cityInfo.civInfo.gameInfo.religions[newMajorityReligion]!!
|
||||
cityInfo.civInfo.addNotification("Your city [${cityInfo.name}] was converted to [${newMajorityReligionObject.getReligionDisplayName()}]!", cityInfo.location, NotificationIcon.Faith)
|
||||
|
||||
|
||||
if (newMajorityReligion in religionsAtSomePointAdopted) return
|
||||
|
||||
|
||||
val religionOwningCiv = newMajorityReligionObject.getFounder()
|
||||
if (religionOwningCiv.hasUnique(UniqueType.StatsWhenAdoptingReligionSpeed) || religionOwningCiv.hasUnique(UniqueType.StatsWhenAdoptingReligion)) {
|
||||
val statsGranted =
|
||||
val statsGranted =
|
||||
(
|
||||
religionOwningCiv.getMatchingUniques(UniqueType.StatsWhenAdoptingReligionSpeed)
|
||||
religionOwningCiv.getMatchingUniques(UniqueType.StatsWhenAdoptingReligionSpeed)
|
||||
+ religionOwningCiv.getMatchingUniques(UniqueType.StatsWhenAdoptingReligion)
|
||||
).map { it.stats }
|
||||
.reduce { acc, stats -> acc + stats }
|
||||
|
||||
|
||||
for ((key, value) in statsGranted)
|
||||
religionOwningCiv.addStat(key, value.toInt())
|
||||
if (cityInfo.location in religionOwningCiv.exploredTiles)
|
||||
@ -140,12 +140,12 @@ class CityInfoReligionManager {
|
||||
}
|
||||
religionsAtSomePointAdopted.add(newMajorityReligion)
|
||||
}
|
||||
|
||||
|
||||
private fun updateNumberOfFollowers(checkForReligionAdoption: Boolean = true) {
|
||||
val oldMajorityReligion =
|
||||
val oldMajorityReligion =
|
||||
if (checkForReligionAdoption) getMajorityReligionName()
|
||||
else null
|
||||
|
||||
|
||||
followers.clear()
|
||||
if (cityInfo.population.population <= 0) return
|
||||
|
||||
@ -172,7 +172,7 @@ class CityInfoReligionManager {
|
||||
remainders[largestRemainder.key] = 0f
|
||||
unallocatedPopulation -= 1
|
||||
}
|
||||
|
||||
|
||||
followers.remove(Constants.noReligionName)
|
||||
|
||||
if (checkForReligionAdoption) {
|
||||
@ -182,24 +182,24 @@ class CityInfoReligionManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getNumberOfFollowers(): Counter<String> {
|
||||
return followers.clone()
|
||||
}
|
||||
|
||||
|
||||
fun getFollowersOf(religion: String): Int? {
|
||||
return followers[religion]
|
||||
}
|
||||
|
||||
|
||||
fun getFollowersOfMajorityReligion(): Int {
|
||||
val majorityReligion = getMajorityReligionName() ?: return 0
|
||||
return followers[majorityReligion]!!
|
||||
}
|
||||
|
||||
|
||||
fun getFollowersOfOtherReligionsThan(religion: String): Int {
|
||||
return followers.filterNot { it.key == religion }.values.sum()
|
||||
}
|
||||
|
||||
|
||||
/** Removes all pantheons except for the one founded by the current owner of the city
|
||||
* Should be called whenever a city changes hands, e.g. conquering and trading
|
||||
*/
|
||||
@ -207,7 +207,7 @@ class CityInfoReligionManager {
|
||||
for (pressure in pressures.keys.toList()) { // Copy the keys because we might modify
|
||||
if (pressure == Constants.noReligionName) continue
|
||||
val correspondingReligion = cityInfo.civInfo.gameInfo.religions[pressure]!!
|
||||
if (correspondingReligion.isPantheon()
|
||||
if (correspondingReligion.isPantheon()
|
||||
&& correspondingReligion.foundingCivName != cityInfo.civInfo.civName
|
||||
) {
|
||||
pressures.remove(pressure)
|
||||
@ -225,7 +225,7 @@ class CityInfoReligionManager {
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getMajorityReligion(): Religion? {
|
||||
return cityInfo.civInfo.gameInfo.religions[getMajorityReligionName()]
|
||||
}
|
||||
@ -233,40 +233,40 @@ class CityInfoReligionManager {
|
||||
private fun getAffectedBySurroundingCities() {
|
||||
if (!cityInfo.civInfo.gameInfo.isReligionEnabled()) return // No religion, no spreading
|
||||
// We don't update the amount of followers yet, as only the end result should matter
|
||||
// If multiple religions would become the majority religion due to pressure,
|
||||
// If multiple religions would become the majority religion due to pressure,
|
||||
// this will make it so we only receive a notification for the last one.
|
||||
// Also, doing it like this increases performance :D
|
||||
if (cityInfo.isHolyCity()) {
|
||||
addPressure(religionThisIsTheHolyCityOf!!,5 * pressureFromAdjacentCities, false)
|
||||
}
|
||||
|
||||
|
||||
val allCitiesWithinSpreadRange =
|
||||
cityInfo.civInfo.gameInfo.getCities()
|
||||
.filter {
|
||||
it != cityInfo
|
||||
&& it.getCenterTile().aerialDistanceTo(cityInfo.getCenterTile()) <= it.religion.getSpreadRange()
|
||||
it != cityInfo
|
||||
&& it.getCenterTile().aerialDistanceTo(cityInfo.getCenterTile()) <= it.religion.getSpreadRange()
|
||||
}
|
||||
for (city in allCitiesWithinSpreadRange) {
|
||||
val majorityReligionOfCity = city.religion.getMajorityReligionName() ?: continue
|
||||
if (!cityInfo.civInfo.gameInfo.religions[majorityReligionOfCity]!!.isMajorReligion()) continue
|
||||
addPressure(majorityReligionOfCity, city.religion.pressureAmountToAdjacentCities(cityInfo), false)
|
||||
addPressure(majorityReligionOfCity, city.religion.pressureAmountToAdjacentCities(cityInfo), false)
|
||||
}
|
||||
|
||||
|
||||
updateNumberOfFollowers()
|
||||
}
|
||||
|
||||
private fun getSpreadRange(): Int {
|
||||
var spreadRange = 10
|
||||
|
||||
|
||||
for (unique in cityInfo.getLocalMatchingUniques(UniqueType.ReligionSpreadDistance)) {
|
||||
spreadRange += unique.params[0].toInt()
|
||||
}
|
||||
|
||||
|
||||
if (getMajorityReligion() != null) {
|
||||
for (unique in getMajorityReligion()!!.getFounder().getMatchingUniques(UniqueType.ReligionSpreadDistance))
|
||||
spreadRange += unique.params[0].toInt()
|
||||
}
|
||||
|
||||
|
||||
return spreadRange
|
||||
}
|
||||
|
||||
@ -297,12 +297,12 @@ class CityInfoReligionManager {
|
||||
if (cityInfo.getCenterTile().civilianUnit?.name == "Inquisitor") return true
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
private fun pressureAmountToAdjacentCities(pressuredCity: CityInfo): Int {
|
||||
var pressure = pressureFromAdjacentCities.toFloat()
|
||||
|
||||
// Follower beliefs of this religion
|
||||
for (unique in cityInfo.getLocalMatchingUniques(UniqueType.NaturalReligionSpreadStrength)) {
|
||||
for (unique in cityInfo.getLocalMatchingUniques(UniqueType.NaturalReligionSpreadStrength)) {
|
||||
if (pressuredCity.matchesFilter(unique.params[1]))
|
||||
pressure *= unique.params[0].toPercent()
|
||||
}
|
||||
@ -316,4 +316,4 @@ class CityInfoReligionManager {
|
||||
|
||||
return pressure.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,12 +9,16 @@ import com.unciv.models.Counter
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.ruleset.GlobalUniques
|
||||
import com.unciv.models.ruleset.ModOptionsConstants
|
||||
import com.unciv.models.ruleset.unique.*
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.StatMap
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.min
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -47,7 +47,7 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques {
|
||||
val rejectionReasons = getRejectionReasons(cityConstructions)
|
||||
return rejectionReasons.all { it.rejectionReason == RejectionReason.Unbuildable }
|
||||
}
|
||||
|
||||
|
||||
fun canBePurchasedWithAnyStat(cityInfo: CityInfo): Boolean {
|
||||
return Stat.values().any { canBePurchasedWithStat(cityInfo, it) }
|
||||
}
|
||||
@ -61,7 +61,7 @@ interface INonPerpetualConstruction : IConstruction, INamed, IHasUniques {
|
||||
if (stat == Stat.Gold) return getBaseGoldCost(cityInfo.civInfo).toInt()
|
||||
|
||||
val conditionalState = StateForConditionals(civInfo = cityInfo.civInfo, cityInfo = cityInfo)
|
||||
|
||||
|
||||
// Can be purchased for [amount] [Stat] [cityFilter]
|
||||
val lowestCostUnique = getMatchingUniques(UniqueType.CanBePurchasedForAmountStat, conditionalState)
|
||||
.filter { it.params[1] == stat.name && cityInfo.matchesFilter(it.params[2]) }
|
||||
@ -145,7 +145,7 @@ class RejectionReasons: HashSet<RejectionReasonInstance>() {
|
||||
RejectionReason.NoPlaceToPutUnit,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum class RejectionReason(val shouldShow: Boolean, val errorMessage: String) {
|
||||
@ -197,7 +197,7 @@ enum class RejectionReason(val shouldShow: Boolean, val errorMessage: String) {
|
||||
|
||||
NoSettlerForOneCityPlayers(false, "No settlers for city-states or one-city challengers"),
|
||||
NoPlaceToPutUnit(true, "No space to place this unit");
|
||||
|
||||
|
||||
fun toInstance(errorMessage: String = this.errorMessage,
|
||||
shouldShow: Boolean = this.shouldShow): RejectionReasonInstance {
|
||||
return RejectionReasonInstance(this, errorMessage, shouldShow)
|
||||
|
@ -2,14 +2,13 @@ package com.unciv.logic.city
|
||||
|
||||
import com.unciv.logic.automation.Automation
|
||||
import com.unciv.logic.civilization.NotificationIcon
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.Counter
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.withItem
|
||||
import com.unciv.ui.utils.withoutItem
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import com.unciv.ui.utils.extensions.withItem
|
||||
import com.unciv.ui.utils.extensions.withoutItem
|
||||
import kotlin.math.floor
|
||||
import kotlin.math.pow
|
||||
|
||||
|
@ -6,13 +6,13 @@ import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.models.metadata.BASE_GAME_DURATION_TURNS
|
||||
import com.unciv.models.ruleset.BeliefType
|
||||
import com.unciv.models.ruleset.Policy
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.StatMap
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
|
@ -13,11 +13,20 @@ import com.unciv.logic.civilization.RuinsManager.RuinsManager
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomacyFlags
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomacyManager
|
||||
import com.unciv.logic.civilization.diplomacy.DiplomaticStatus
|
||||
import com.unciv.logic.map.*
|
||||
import com.unciv.logic.map.MapShape
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.UnitMovementAlgorithms
|
||||
import com.unciv.logic.trade.TradeEvaluation
|
||||
import com.unciv.logic.trade.TradeRequest
|
||||
import com.unciv.models.Counter
|
||||
import com.unciv.models.ruleset.*
|
||||
import com.unciv.models.ruleset.Building
|
||||
import com.unciv.models.ruleset.Difficulty
|
||||
import com.unciv.models.ruleset.Era
|
||||
import com.unciv.models.ruleset.ModOptionsConstants
|
||||
import com.unciv.models.ruleset.Nation
|
||||
import com.unciv.models.ruleset.Policy
|
||||
import com.unciv.models.ruleset.Victory
|
||||
import com.unciv.models.ruleset.tile.ResourceSupplyList
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.TileResource
|
||||
@ -29,8 +38,8 @@ import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.MayaCalendar
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.withItem
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import com.unciv.ui.utils.extensions.withItem
|
||||
import com.unciv.ui.victoryscreen.RankingType
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.unciv.logic.civilization
|
||||
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
|
||||
class GoldenAgeManager {
|
||||
@Transient
|
||||
@ -47,4 +47,4 @@ class GoldenAgeManager {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import com.unciv.models.ruleset.unique.UniqueTriggerActivation
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.equalsPlaceholderText
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
@ -17,8 +17,8 @@ import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.translations.fillPlaceholders
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.randomWeighted
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.randomWeighted
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.max
|
||||
import kotlin.random.Random
|
||||
|
||||
|
@ -6,7 +6,7 @@ import com.unciv.models.Religion
|
||||
import com.unciv.models.ruleset.Belief
|
||||
import com.unciv.models.ruleset.BeliefType
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.random.Random
|
||||
|
||||
class ReligionManager {
|
||||
|
@ -4,17 +4,15 @@ import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.map.MapSize
|
||||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.models.ruleset.Era
|
||||
import com.unciv.models.ruleset.tech.Technology
|
||||
import com.unciv.models.ruleset.unique.UniqueMap
|
||||
import com.unciv.models.ruleset.unique.UniqueTriggerActivation
|
||||
import com.unciv.models.ruleset.tech.Technology
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.ui.utils.MayaCalendar
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.withItem
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import com.unciv.ui.utils.extensions.withItem
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
@ -49,7 +47,7 @@ class TechManager {
|
||||
|
||||
var freeTechs = 0
|
||||
// For calculating score
|
||||
var repeatingTechsResearched = 0
|
||||
var repeatingTechsResearched = 0
|
||||
|
||||
/** For calculating Great Scientist yields - see https://civilization.fandom.com/wiki/Great_Scientist_(Civ5) */
|
||||
var scienceOfLast8Turns = IntArray(8) { 0 }
|
||||
@ -120,7 +118,7 @@ class TechManager {
|
||||
|
||||
fun researchOfTech(TechName: String?) = techsInProgress[TechName] ?: 0
|
||||
// Was once duplicated as fun scienceSpentOnTech(tech: String): Int
|
||||
|
||||
|
||||
fun remainingScienceToTech(techName: String) = costOfTech(techName) - researchOfTech(techName)
|
||||
|
||||
fun turnsToTech(techName: String) = when {
|
||||
|
@ -2,13 +2,19 @@ package com.unciv.logic.civilization.diplomacy
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.civilization.*
|
||||
import com.unciv.logic.civilization.AlertType
|
||||
import com.unciv.logic.civilization.CityStatePersonality
|
||||
import com.unciv.logic.civilization.CityStateType
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.NotificationIcon
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.civilization.PopupAlert
|
||||
import com.unciv.logic.trade.Trade
|
||||
import com.unciv.logic.trade.TradeOffer
|
||||
import com.unciv.logic.trade.TradeType
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.tile.ResourceSupplyList
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
@ -12,17 +12,20 @@ import com.unciv.logic.city.RejectionReason
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.LocationAction
|
||||
import com.unciv.logic.civilization.NotificationIcon
|
||||
import com.unciv.models.helpers.UnitMovementMemoryType
|
||||
import com.unciv.models.UnitActionType
|
||||
import com.unciv.models.helpers.UnitMovementMemoryType
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.models.ruleset.tile.TileImprovement
|
||||
import com.unciv.models.ruleset.unique.*
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueMap
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.ruleset.unit.UnitType
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.ui.utils.filterAndLogic
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.filterAndLogic
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.pow
|
||||
|
||||
|
@ -8,14 +8,21 @@ import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.tile.*
|
||||
import com.unciv.models.ruleset.unique.*
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.Terrain
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.models.ruleset.tile.TileImprovement
|
||||
import com.unciv.models.ruleset.tile.TileResource
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.min
|
||||
import kotlin.random.Random
|
||||
|
@ -5,7 +5,10 @@ import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.HexMath
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.map.*
|
||||
import com.unciv.logic.map.MapResources
|
||||
import com.unciv.logic.map.MapShape
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.Terrain
|
||||
@ -17,8 +20,12 @@ import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.translations.equalsPlaceholderText
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.ui.utils.randomWeighted
|
||||
import kotlin.math.*
|
||||
import com.unciv.ui.utils.extensions.randomWeighted
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
|
||||
class MapRegions (val ruleset: Ruleset){
|
||||
|
@ -13,7 +13,7 @@ import com.unciv.models.metadata.GameSettings
|
||||
import com.unciv.ui.crashhandling.CRASH_HANDLING_DAEMON_SCOPE
|
||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
import com.unciv.ui.utils.isLargerThan
|
||||
import com.unciv.ui.utils.extensions.isLargerThan
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
@ -8,7 +8,7 @@ import com.unciv.logic.event.EventBus
|
||||
import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached
|
||||
import com.unciv.logic.multiplayer.storage.OnlineMultiplayerGameSaver
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
import com.unciv.ui.utils.isLargerThan
|
||||
import com.unciv.ui.utils.extensions.isLargerThan
|
||||
import java.io.FileNotFoundException
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
@ -1,10 +1,14 @@
|
||||
package com.unciv.logic.multiplayer.storage
|
||||
|
||||
import com.unciv.utils.debug
|
||||
import com.unciv.json.json
|
||||
import com.unciv.ui.utils.UncivDateFormat.parseDate
|
||||
import com.unciv.ui.utils.extensions.UncivDateFormat.parseDate
|
||||
import com.unciv.utils.Log
|
||||
import java.io.*
|
||||
import com.unciv.utils.debug
|
||||
import java.io.BufferedReader
|
||||
import java.io.DataOutputStream
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.InputStream
|
||||
import java.io.InputStreamReader
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.nio.charset.Charset
|
||||
|
@ -9,7 +9,7 @@ import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
||||
import com.unciv.models.ruleset.ModOptionsConstants
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import com.unciv.ui.victoryscreen.RankingType
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sqrt
|
||||
|
@ -1,79 +1,34 @@
|
||||
package com.unciv.models
|
||||
|
||||
private enum class UncivSoundConstants (val value: String) {
|
||||
Click("click"),
|
||||
Fortify("fortify"),
|
||||
Promote("promote"),
|
||||
Upgrade("upgrade"),
|
||||
Setup("setup"),
|
||||
Chimes("chimes"),
|
||||
Coin("coin"),
|
||||
Choir("choir"),
|
||||
Fire("fire"),
|
||||
Policy("policy"),
|
||||
Paper("paper"),
|
||||
Whoosh("whoosh"),
|
||||
Bombard("bombard"),
|
||||
Slider("slider"),
|
||||
Construction("construction"),
|
||||
Swap("swap"),
|
||||
Silent(""),
|
||||
Custom("")
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an Unciv Sound, either from a predefined set or custom with a specified filename.
|
||||
*/
|
||||
class UncivSound private constructor (
|
||||
private val type: UncivSoundConstants,
|
||||
filename: String? = null
|
||||
) {
|
||||
data class UncivSound(
|
||||
/** The base filename without extension. */
|
||||
val value: String = filename ?: type.value
|
||||
|
||||
/*
|
||||
init {
|
||||
// Checking contract "use non-custom *w/o* filename OR custom *with* one
|
||||
// Removed due to private constructor
|
||||
if ((type == UncivSoundConstants.Custom) == filename.isNullOrEmpty()) {
|
||||
throw IllegalArgumentException("Invalid UncivSound constructor arguments")
|
||||
}
|
||||
}
|
||||
*/
|
||||
val fileName: String
|
||||
) {
|
||||
/** For serialization */
|
||||
private constructor() : this("")
|
||||
|
||||
companion object {
|
||||
val Click = UncivSound(UncivSoundConstants.Click)
|
||||
val Fortify = UncivSound(UncivSoundConstants.Fortify)
|
||||
val Promote = UncivSound(UncivSoundConstants.Promote)
|
||||
val Upgrade = UncivSound(UncivSoundConstants.Upgrade)
|
||||
val Setup = UncivSound(UncivSoundConstants.Setup)
|
||||
val Chimes = UncivSound(UncivSoundConstants.Chimes)
|
||||
val Coin = UncivSound(UncivSoundConstants.Coin)
|
||||
val Choir = UncivSound(UncivSoundConstants.Choir)
|
||||
val Policy = UncivSound(UncivSoundConstants.Policy)
|
||||
val Paper = UncivSound(UncivSoundConstants.Paper)
|
||||
val Whoosh = UncivSound(UncivSoundConstants.Whoosh)
|
||||
val Bombard = UncivSound(UncivSoundConstants.Bombard)
|
||||
val Slider = UncivSound(UncivSoundConstants.Slider)
|
||||
val Construction = UncivSound(UncivSoundConstants.Construction)
|
||||
val Swap = UncivSound(UncivSoundConstants.Swap)
|
||||
val Silent = UncivSound(UncivSoundConstants.Silent)
|
||||
val Fire = UncivSound(UncivSoundConstants.Fire)
|
||||
/** Creates an UncivSound instance for a custom sound.
|
||||
* @param filename The base filename without extension.
|
||||
*/
|
||||
fun custom(filename: String) = UncivSound(UncivSoundConstants.Custom, filename)
|
||||
val Bombard = UncivSound("bombard")
|
||||
val Chimes = UncivSound("chimes")
|
||||
val Choir = UncivSound("choir")
|
||||
val Click = UncivSound("click")
|
||||
val Coin = UncivSound("coin")
|
||||
val Construction = UncivSound("construction")
|
||||
val Fire = UncivSound("fire")
|
||||
val Fortify = UncivSound("fortify")
|
||||
val Notification1 = UncivSound("notification1")
|
||||
val Notification2 = UncivSound("notification2")
|
||||
val Paper = UncivSound("paper")
|
||||
val Policy = UncivSound("policy")
|
||||
val Promote = UncivSound("promote")
|
||||
val Setup = UncivSound("setup")
|
||||
val Silent = UncivSound("")
|
||||
val Slider = UncivSound("slider")
|
||||
val Swap = UncivSound("swap")
|
||||
val Upgrade = UncivSound("upgrade")
|
||||
val Whoosh = UncivSound("whoosh")
|
||||
}
|
||||
|
||||
// overrides ensure usability as hash key
|
||||
override fun hashCode(): Int {
|
||||
return type.hashCode() xor value.hashCode()
|
||||
}
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other == null || other !is UncivSound) return false
|
||||
if (type != other.type) return false
|
||||
return type != UncivSoundConstants.Custom || value == other.value
|
||||
}
|
||||
|
||||
override fun toString(): String = value
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,11 @@ import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.Constants
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.ui.utils.darken
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.extensions.darken
|
||||
|
||||
|
||||
/** Unit Actions - class - carries dynamic data and actual execution.
|
||||
@ -54,7 +54,7 @@ data class UnitAction(
|
||||
}
|
||||
|
||||
/** Unit Actions - generic enum with static properties
|
||||
*
|
||||
*
|
||||
* @param value _default_ label to display, can be overridden in UnitAction instantiation
|
||||
* @param imageGetter optional lambda to get an Icon - `null` if icon is dependent on outside factors and needs special handling
|
||||
* @param key keyboard binding - can be a [KeyCharAndCode], a [Char], or omitted.
|
||||
@ -97,7 +97,7 @@ enum class UnitActionType(
|
||||
{ imageGetPromote() }, 'o', UncivSound.Promote),
|
||||
Upgrade("Upgrade",
|
||||
null, 'u', UncivSound.Upgrade),
|
||||
Pillage("Pillage",
|
||||
Pillage("Pillage",
|
||||
{ ImageGetter.getImage("OtherIcons/Pillage") }, 'p'),
|
||||
Paradrop("Paradrop",
|
||||
{ ImageGetter.getUnitIcon("Paratrooper") }, 'p'),
|
||||
|
@ -4,12 +4,14 @@ import com.badlogic.gdx.Application
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import java.text.Collator
|
||||
import java.time.Duration
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KMutableProperty0
|
||||
|
||||
data class WindowState (val width: Int = 900, val height: Int = 600)
|
||||
|
||||
@ -167,5 +169,30 @@ class GameSettingsMultiplayer {
|
||||
var statusButtonInSinglePlayer = false
|
||||
var currentGameRefreshDelay = Duration.ofSeconds(10)
|
||||
var allGameRefreshDelay = Duration.ofMinutes(5)
|
||||
var currentGameTurnNotificationSound: UncivSound = UncivSound.Silent
|
||||
var otherGameTurnNotificationSound: UncivSound = UncivSound.Silent
|
||||
var hideDropboxWarning = false
|
||||
}
|
||||
|
||||
enum class GameSetting(
|
||||
val kClass: KClass<*>,
|
||||
private val propertyGetter: (GameSettings) -> KMutableProperty0<*>
|
||||
) {
|
||||
// Uncomment these once they are refactored to send events on change
|
||||
// MULTIPLAYER_USER_ID(String::class, { it.multiplayer::userId }),
|
||||
// MULTIPLAYER_SERVER(String::class, { it.multiplayer::server }),
|
||||
// MULTIPLAYER_STATUSBUTTON_IN_SINGLEPLAYER(Boolean::class, { it.multiplayer::statusButtonInSinglePlayer }),
|
||||
// MULTIPLAYER_TURN_CHECKER_ENABLED(Boolean::class, { it.multiplayer::turnCheckerEnabled }),
|
||||
// MULTIPLAYER_TURN_CHECKER_PERSISTENT_NOTIFICATION_ENABLED(Boolean::class, { it.multiplayer::turnCheckerPersistentNotificationEnabled }),
|
||||
// MULTIPLAYER_HIDE_DROPBOX_WARNING(Boolean::class, { it.multiplayer::hideDropboxWarning }),
|
||||
MULTIPLAYER_TURN_CHECKER_DELAY(Duration::class, { it.multiplayer::turnCheckerDelay }),
|
||||
MULTIPLAYER_CURRENT_GAME_REFRESH_DELAY(Duration::class, { it.multiplayer::currentGameRefreshDelay }),
|
||||
MULTIPLAYER_ALL_GAME_REFRESH_DELAY(Duration::class, { it.multiplayer::allGameRefreshDelay }),
|
||||
MULTIPLAYER_CURRENT_GAME_TURN_NOTIFICATION_SOUND(UncivSound::class, { it.multiplayer::currentGameTurnNotificationSound }),
|
||||
MULTIPLAYER_OTHER_GAME_TURN_NOTIFICATION_SOUND(UncivSound::class, { it.multiplayer::otherGameTurnNotificationSound });
|
||||
|
||||
/** **Warning:** It is the obligation of the caller to select the same type [T] that the [kClass] of this property has */
|
||||
fun <T> getProperty(settings: GameSettings): KMutableProperty0<T> {
|
||||
return propertyGetter(settings) as KMutableProperty0<T>
|
||||
}
|
||||
}
|
||||
|
13
core/src/com/unciv/models/metadata/SettingsEvents.kt
Normal file
13
core/src/com/unciv/models/metadata/SettingsEvents.kt
Normal file
@ -0,0 +1,13 @@
|
||||
package com.unciv.models.metadata
|
||||
|
||||
import com.unciv.logic.event.Event
|
||||
import com.unciv.models.UncivSound
|
||||
|
||||
/** **Warning:** this event is in the process of completion and **not** used for all settings yet! **Only the settings in [GameSetting] get events sent!** */
|
||||
interface SettingsPropertyChanged : Event {
|
||||
val gameSetting: GameSetting
|
||||
}
|
||||
|
||||
interface SettingsPropertyUncivSoundChanged : SettingsPropertyChanged {
|
||||
val value: UncivSound
|
||||
}
|
@ -1,19 +1,30 @@
|
||||
package com.unciv.models.ruleset
|
||||
|
||||
import com.unciv.logic.city.*
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.INonPerpetualConstruction
|
||||
import com.unciv.logic.city.RejectionReason
|
||||
import com.unciv.logic.city.RejectionReasons
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.Counter
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.TileImprovement
|
||||
import com.unciv.models.ruleset.unique.*
|
||||
import com.unciv.models.ruleset.unique.LocalUniqueCache
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueParameterType
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueTriggerActivation
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.fillPlaceholders
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.getConsumesAmountString
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.getConsumesAmountString
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.pow
|
||||
|
||||
|
||||
@ -156,7 +167,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
|
||||
if (maintenance != 0 && !isFree) lines += "{Maintenance cost}: $maintenance {Gold}"
|
||||
if (showAdditionalInfo && missingCities.isNotEmpty()) {
|
||||
// Could be red. But IMO that should be done by enabling GDX's ColorMarkupLanguage globally instead of adding a separate label.
|
||||
lines += "\n" +
|
||||
lines += "\n" +
|
||||
"[${cityInfo.civInfo.getEquivalentBuilding(missingUnique!!.params[0])}] required:".tr() +
|
||||
" " + missingCities.joinToString(", ") { "{${it.name}}" }
|
||||
// Can't nest square bracket placeholders inside curlies, and don't see any way to define wildcard placeholders. So run translation explicitly on base text.
|
||||
@ -164,7 +175,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
|
||||
return lines.joinToString("\n") { it.tr() }.trim()
|
||||
}
|
||||
|
||||
fun getStats(city: CityInfo,
|
||||
fun getStats(city: CityInfo,
|
||||
/* By default, do not cache - if we're getting stats for only one building this isn't efficient.
|
||||
* Only use a cache if it was sent to us from outside, which means we can use the results for other buildings. */
|
||||
localUniqueCache: LocalUniqueCache = LocalUniqueCache(false)): Stats {
|
||||
@ -193,12 +204,12 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction {
|
||||
fun getStatPercentageBonuses(cityInfo: CityInfo?, localUniqueCache: LocalUniqueCache = LocalUniqueCache(false)): Stats {
|
||||
val stats = percentStatBonus?.clone() ?: Stats()
|
||||
val civInfo = cityInfo?.civInfo ?: return stats // initial stats
|
||||
|
||||
|
||||
for (unique in localUniqueCache.get("StatPercentFromObject", civInfo.getMatchingUniques(UniqueType.StatPercentFromObject))) {
|
||||
if (matchesFilter(unique.params[2]))
|
||||
stats.add(Stat.valueOf(unique.params[1]), unique.params[0].toFloat())
|
||||
}
|
||||
|
||||
|
||||
for (unique in localUniqueCache.get("AllStatsPercentFromObject", civInfo.getMatchingUniques(UniqueType.AllStatsPercentFromObject))) {
|
||||
if (!matchesFilter(unique.params[1])) continue
|
||||
for (stat in Stat.values()) {
|
||||
|
@ -3,10 +3,14 @@ package com.unciv.models.ruleset
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.logic.civilization.CityStateType
|
||||
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
|
||||
import com.unciv.models.ruleset.unique.*
|
||||
import com.unciv.models.ruleset.unique.IHasUniques
|
||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.colorFromRGB
|
||||
import com.unciv.ui.utils.extensions.colorFromRGB
|
||||
|
||||
class Era : RulesetObject(), IHasUniques {
|
||||
var eraNumber: Int = -1
|
||||
|
@ -12,7 +12,7 @@ import com.unciv.models.translations.squareBraceRegex
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.colorFromRGB
|
||||
import com.unciv.ui.utils.extensions.colorFromRGB
|
||||
|
||||
class Nation : RulesetObject() {
|
||||
var leaderName = ""
|
||||
@ -37,16 +37,16 @@ class Nation : RulesetObject() {
|
||||
var uniqueText = ""
|
||||
var innerColor: List<Int>? = null
|
||||
var startBias = ArrayList<String>()
|
||||
|
||||
|
||||
var startIntroPart1 = ""
|
||||
var startIntroPart2 = ""
|
||||
|
||||
/* Properties present in json but not yet implemented:
|
||||
var adjective = ArrayList<String>()
|
||||
*/
|
||||
|
||||
|
||||
var favoredReligion: String? = null
|
||||
|
||||
|
||||
@Transient
|
||||
private lateinit var outerColorObject: Color
|
||||
fun getOuterColor(): Color = outerColorObject
|
||||
@ -118,7 +118,7 @@ class Nation : RulesetObject() {
|
||||
val link = if ('[' !in it.value) it.value
|
||||
else squareBraceRegex.find(it.value)!!.groups[1]!!.value
|
||||
textList += FormattedLine(
|
||||
(if (it.index == 0) "[Start bias:] " else "") + it.value.tr(), // extra tr because tr cannot nest {[]}
|
||||
(if (it.index == 0) "[Start bias:] " else "") + it.value.tr(), // extra tr because tr cannot nest {[]}
|
||||
link = "Terrain/$link",
|
||||
indent = if (it.index == 0) 0 else 1,
|
||||
iconCrossed = it.value.startsWith("Avoid "))
|
||||
@ -170,7 +170,7 @@ class Nation : RulesetObject() {
|
||||
if (allMercantileResources.isNotEmpty()) {
|
||||
textList += FormattedLine()
|
||||
textList += FormattedLine("The unique luxury is one of:")
|
||||
allMercantileResources.forEach {
|
||||
allMercantileResources.forEach {
|
||||
textList += FormattedLine(it.name, it.makeLink(), indent = 1)
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ import com.unciv.models.stats.NamedStats
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.fillPlaceholders
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.colorFromRGB
|
||||
import com.unciv.ui.utils.extensions.colorFromRGB
|
||||
import com.unciv.ui.utils.getRelativeTextDistance
|
||||
import com.unciv.utils.Log
|
||||
import com.unciv.utils.debug
|
||||
|
@ -3,12 +3,12 @@ package com.unciv.models.ruleset
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.unciv.Constants
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.Counter
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.models.translations.getPlaceholderText
|
||||
import com.unciv.ui.utils.toTextButton
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
|
||||
|
||||
enum class MilestoneType(val text: String) {
|
||||
@ -41,7 +41,7 @@ class Victory : INamed {
|
||||
CityStates,
|
||||
Score,
|
||||
}
|
||||
|
||||
|
||||
override var name = ""
|
||||
val victoryScreenHeader = "Do things to win!"
|
||||
val hiddenInVictoryScreen = false
|
||||
@ -57,10 +57,10 @@ class Victory : INamed {
|
||||
parts.add(spaceshipPart, 1)
|
||||
parts
|
||||
}
|
||||
|
||||
|
||||
val victoryString = "Your civilization stands above all others! The exploits of your people shall be remembered until the end of civilization itself!"
|
||||
val defeatString = "You have been defeated. Your civilization has been overwhelmed by its many foes. But your people do not despair, for they know that one day you shall return - and lead them forward to victory!"
|
||||
|
||||
|
||||
fun enablesMaxTurns(): Boolean = milestoneObjects.any { it.type == MilestoneType.ScoreAfterTimeOut }
|
||||
fun getThingsToFocus(civInfo: CivilizationInfo): Set<Focus> = milestoneObjects
|
||||
.filter { !it.hasBeenCompletedBy(civInfo) }
|
||||
@ -78,7 +78,7 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
incompleteSpaceshipParts.remove(civInfo.victoryManager.currentsSpaceshipParts)
|
||||
return incompleteSpaceshipParts
|
||||
}
|
||||
|
||||
|
||||
fun hasBeenCompletedBy(civInfo: CivilizationInfo): Boolean {
|
||||
return when (type!!) {
|
||||
MilestoneType.BuiltBuilding ->
|
||||
@ -101,9 +101,9 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
&& civInfo == civInfo.gameInfo.civilizations.maxByOrNull { it.calculateTotalScore() }
|
||||
}
|
||||
MilestoneType.WorldReligion -> {
|
||||
civInfo.gameInfo.isReligionEnabled()
|
||||
civInfo.gameInfo.isReligionEnabled()
|
||||
&& civInfo.religionManager.religion != null
|
||||
&& civInfo.gameInfo.civilizations.all {
|
||||
&& civInfo.gameInfo.civilizations.all {
|
||||
it.religionManager.isMajorityReligionForCiv(civInfo.religionManager.religion!!)
|
||||
}
|
||||
}
|
||||
@ -116,11 +116,11 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
else textButton.color = Color.GRAY
|
||||
return textButton
|
||||
}
|
||||
|
||||
|
||||
fun getVictoryScreenButtonHeaderText(completed: Boolean, civInfo: CivilizationInfo): String {
|
||||
return when (type!!) {
|
||||
MilestoneType.BuildingBuiltGlobally, MilestoneType.WinDiplomaticVote,
|
||||
MilestoneType.ScoreAfterTimeOut, MilestoneType.BuiltBuilding ->
|
||||
MilestoneType.BuildingBuiltGlobally, MilestoneType.WinDiplomaticVote,
|
||||
MilestoneType.ScoreAfterTimeOut, MilestoneType.BuiltBuilding ->
|
||||
uniqueDescription
|
||||
MilestoneType.CompletePolicyBranches -> {
|
||||
val amountToDo = params[0]
|
||||
@ -148,9 +148,9 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
val incompleteSpaceshipParts = parentVictory.requiredSpaceshipPartsAsCounter.clone()
|
||||
val amountToDo = incompleteSpaceshipParts.sumValues()
|
||||
incompleteSpaceshipParts.remove(completeSpaceshipParts)
|
||||
|
||||
|
||||
val amountDone = amountToDo - incompleteSpaceshipParts.sumValues()
|
||||
|
||||
|
||||
"{$uniqueDescription} ($amountDone/$amountToDo)"
|
||||
}
|
||||
MilestoneType.WorldReligion -> {
|
||||
@ -168,10 +168,10 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getVictoryScreenButtons(completionStatus: Victory.CompletionStatus, civInfo: CivilizationInfo): List<TextButton> {
|
||||
val headerButton = getMilestoneButton(
|
||||
getVictoryScreenButtonHeaderText(completionStatus == Victory.CompletionStatus.Completed, civInfo),
|
||||
getVictoryScreenButtonHeaderText(completionStatus == Victory.CompletionStatus.Completed, civInfo),
|
||||
completionStatus == Victory.CompletionStatus.Completed
|
||||
)
|
||||
if (completionStatus == Victory.CompletionStatus.Completed || completionStatus == Victory.CompletionStatus.Incomplete) {
|
||||
@ -182,12 +182,12 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
val buttons = mutableListOf(headerButton)
|
||||
when (type) {
|
||||
// No extra buttons necessary
|
||||
MilestoneType.BuiltBuilding, MilestoneType.BuildingBuiltGlobally,
|
||||
MilestoneType.ScoreAfterTimeOut, MilestoneType.WinDiplomaticVote -> {}
|
||||
MilestoneType.BuiltBuilding, MilestoneType.BuildingBuiltGlobally,
|
||||
MilestoneType.ScoreAfterTimeOut, MilestoneType.WinDiplomaticVote -> {}
|
||||
MilestoneType.AddedSSPartsInCapital -> {
|
||||
val completedSpaceshipParts = civInfo.victoryManager.currentsSpaceshipParts
|
||||
val incompleteSpaceshipParts = getIncompleteSpaceshipParts(civInfo)
|
||||
|
||||
|
||||
for (part in completedSpaceshipParts) {
|
||||
repeat(part.value) {
|
||||
buttons.add(getMilestoneButton(part.key, true))
|
||||
@ -199,7 +199,7 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MilestoneType.DestroyAllPlayers -> {
|
||||
val majorCivs = civInfo.gameInfo.civilizations.filter { it.isMajorCiv() && it != civInfo }
|
||||
for (civ in majorCivs) {
|
||||
@ -209,7 +209,7 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
buttons.add(getMilestoneButton(milestoneText, !civ.isAlive()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MilestoneType.CaptureAllCapitals -> {
|
||||
val originalCapitals = civInfo.gameInfo.getCities().filter { it.isOriginalCapital }
|
||||
for (city in originalCapitals) {
|
||||
@ -219,7 +219,7 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
buttons.add(getMilestoneButton(milestoneText, city.civInfo == civInfo))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MilestoneType.CompletePolicyBranches -> {
|
||||
for (branch in civInfo.gameInfo.ruleSet.policyBranches.values) {
|
||||
val finisher = branch.policies.last().name
|
||||
@ -241,7 +241,7 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
}
|
||||
return buttons
|
||||
}
|
||||
|
||||
|
||||
fun getFocus(civInfo: CivilizationInfo): Victory.Focus {
|
||||
val ruleset = civInfo.gameInfo.ruleSet
|
||||
return when (type!!) {
|
||||
@ -275,4 +275,4 @@ class Milestone(val uniqueDescription: String, private val parentVictory: Victor
|
||||
MilestoneType.WorldReligion -> Victory.Focus.Faith
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import com.unciv.models.ruleset.unique.UniqueFlag
|
||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.colorFromRGB
|
||||
import com.unciv.ui.utils.extensions.colorFromRGB
|
||||
|
||||
class Terrain : RulesetStatsObject() {
|
||||
|
||||
@ -43,7 +43,7 @@ class Terrain : RulesetStatsObject() {
|
||||
|
||||
// Shouldn't this just be a lazy property so it's automatically cached?
|
||||
fun isRough(): Boolean = hasUnique(UniqueType.RoughTerrain)
|
||||
|
||||
|
||||
/** Tests base terrains, features and natural wonders whether they should be treated as Land/Water.
|
||||
* Currently only used for civilopedia display, as other code can test the tile itself.
|
||||
*/
|
||||
|
@ -13,9 +13,8 @@ import com.unciv.models.ruleset.unique.UniqueTarget
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import com.unciv.ui.worldscreen.unit.UnitActions
|
||||
import java.util.*
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class TileImprovement : RulesetStatsObject() {
|
||||
|
@ -6,9 +6,10 @@ import com.unciv.models.ruleset.BeliefType
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.unique.UniqueParameterType.Companion.guessTypeForTranslationWriter
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.translations.TranslationFileWriter // for Kdoc only
|
||||
import com.unciv.ui.utils.filterCompositeLogic
|
||||
import com.unciv.models.translations.TranslationFileWriter
|
||||
import com.unciv.ui.utils.extensions.filterCompositeLogic
|
||||
|
||||
// 'region' names beginning with an underscore are used here for a prettier "Structure window" - they go in front ot the rest.
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
package com.unciv.models.ruleset.unit
|
||||
|
||||
import com.unciv.logic.city.*
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.INonPerpetualConstruction
|
||||
import com.unciv.logic.city.RejectionReason
|
||||
import com.unciv.logic.city.RejectionReasons
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
@ -13,12 +17,9 @@ import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.filterAndLogic
|
||||
import com.unciv.ui.utils.getConsumesAmountString
|
||||
import com.unciv.ui.utils.toPercent
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.collections.HashSet
|
||||
import com.unciv.ui.utils.extensions.filterAndLogic
|
||||
import com.unciv.ui.utils.extensions.getConsumesAmountString
|
||||
import com.unciv.ui.utils.extensions.toPercent
|
||||
import kotlin.math.pow
|
||||
|
||||
// This is BaseUnit because Unit is already a base Kotlin class and to avoid mixing the two up
|
||||
@ -46,8 +47,8 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
var promotions = HashSet<String>()
|
||||
var obsoleteTech: String? = null
|
||||
var upgradesTo: String? = null
|
||||
val specialUpgradesTo: String? by lazy {
|
||||
getMatchingUniques(UniqueType.RuinsUpgrade).map { it.params[0] }.firstOrNull()
|
||||
val specialUpgradesTo: String? by lazy {
|
||||
getMatchingUniques(UniqueType.RuinsUpgrade).map { it.params[0] }.firstOrNull()
|
||||
}
|
||||
var replaces: String? = null
|
||||
var uniqueTo: String? = null
|
||||
@ -238,8 +239,8 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
unit.owner = civInfo.civName
|
||||
|
||||
// must be after setting name & civInfo because it sets the baseUnit according to the name
|
||||
// and the civInfo is required for using `hasUnique` when determining its movement options
|
||||
unit.setTransients(civInfo.gameInfo.ruleSet)
|
||||
// and the civInfo is required for using `hasUnique` when determining its movement options
|
||||
unit.setTransients(civInfo.gameInfo.ruleSet)
|
||||
|
||||
return unit
|
||||
}
|
||||
@ -259,7 +260,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
override fun canBePurchasedWithStat(cityInfo: CityInfo?, stat: Stat): Boolean {
|
||||
if (cityInfo == null) return super.canBePurchasedWithStat(cityInfo, stat)
|
||||
val conditionalState = StateForConditionals(civInfo = cityInfo.civInfo, cityInfo = cityInfo)
|
||||
|
||||
|
||||
return (cityInfo.getMatchingUniques(UniqueType.BuyUnitsIncreasingCost, conditionalState)
|
||||
.any {
|
||||
it.params[2] == stat.name
|
||||
@ -394,17 +395,17 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
val rejectionReasons = RejectionReasons()
|
||||
val ruleSet = civInfo.gameInfo.ruleSet
|
||||
|
||||
if (requiredTech != null && !civInfo.tech.isResearched(requiredTech!!))
|
||||
rejectionReasons.add(RejectionReason.RequiresTech.toInstance("$requiredTech not researched"))
|
||||
if (requiredTech != null && !civInfo.tech.isResearched(requiredTech!!))
|
||||
rejectionReasons.add(RejectionReason.RequiresTech.toInstance("$requiredTech not researched"))
|
||||
if (obsoleteTech != null && civInfo.tech.isResearched(obsoleteTech!!))
|
||||
rejectionReasons.add(RejectionReason.Obsoleted.toInstance("Obsolete by $obsoleteTech"))
|
||||
|
||||
if (uniqueTo != null && uniqueTo != civInfo.civName)
|
||||
if (uniqueTo != null && uniqueTo != civInfo.civName)
|
||||
rejectionReasons.add(RejectionReason.UniqueToOtherNation.toInstance("Unique to $uniqueTo"))
|
||||
if (ruleSet.units.values.any { it.uniqueTo == civInfo.civName && it.replaces == name })
|
||||
rejectionReasons.add(RejectionReason.ReplacedByOurUnique.toInstance("Our unique unit replaces this"))
|
||||
|
||||
if (!civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled && isNuclearWeapon())
|
||||
if (!civInfo.gameInfo.gameParameters.nuclearWeaponsEnabled && isNuclearWeapon())
|
||||
rejectionReasons.add(RejectionReason.DisabledBySetting)
|
||||
|
||||
for (unique in uniqueObjects) {
|
||||
@ -481,11 +482,11 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
|
||||
// If this unit has special abilities that need to be kept track of, start doing so here
|
||||
if (unit.hasUnique(UniqueType.ReligiousUnit) && civInfo.gameInfo.isReligionEnabled()) {
|
||||
unit.religion =
|
||||
unit.religion =
|
||||
if (unit.hasUnique(UniqueType.TakeReligionOverBirthCity))
|
||||
civInfo.religionManager.religion?.name
|
||||
else cityConstructions.cityInfo.religion.getMajorityReligionName()
|
||||
|
||||
|
||||
unit.setupAbilityUses(cityConstructions.cityInfo)
|
||||
}
|
||||
|
||||
@ -509,7 +510,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
if (unit.matchesFilter(unique.params[0]))
|
||||
XP += unique.params[1].toInt()
|
||||
}
|
||||
unit.promotions.XP = XP
|
||||
unit.promotions.XP = XP
|
||||
|
||||
for (unique in cityConstructions.cityInfo.getMatchingUniques(UniqueType.UnitStartingPromotions)
|
||||
.filter { cityConstructions.cityInfo.matchesFilter(it.params[1]) }) {
|
||||
@ -613,7 +614,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
||||
&& (uniqueObjects + getType().uniqueObjects)
|
||||
.any { it.isOfType(UniqueType.Strength)
|
||||
&& it.params[0].toInt() > 0
|
||||
&& it.conditionals.any { conditional -> conditional.isOfType(UniqueType.ConditionalVsCity) }
|
||||
&& it.conditionals.any { conditional -> conditional.isOfType(UniqueType.ConditionalVsCity) }
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -8,9 +8,8 @@ import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.utils.Log
|
||||
import com.unciv.utils.debug
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.collections.LinkedHashSet
|
||||
|
||||
/**
|
||||
* This collection holds all translations for the game.
|
||||
|
@ -2,12 +2,12 @@ package com.unciv.ui
|
||||
|
||||
import com.unciv.MainMenuScreen
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.options.OptionsPopup
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.utils.enable
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.LanguageTable
|
||||
import com.unciv.ui.utils.LanguageTable.Companion.addLanguageTables
|
||||
import com.unciv.ui.options.OptionsPopup
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
|
||||
/** A [PickerScreen] to select a language, used once on the initial run after a fresh install.
|
||||
* After that, [OptionsPopup] provides the functionality.
|
||||
|
@ -4,8 +4,8 @@ import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.g2d.Batch
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||
import com.badlogic.gdx.utils.viewport.Viewport
|
||||
import com.unciv.ui.utils.wrapCrashHandling
|
||||
import com.unciv.ui.utils.wrapCrashHandlingUnit
|
||||
import com.unciv.ui.crashhandling.wrapCrashHandling
|
||||
import com.unciv.ui.crashhandling.wrapCrashHandlingUnit
|
||||
|
||||
|
||||
/** Main stage for the game. Safely brings the game to a [CrashScreen] if any event handlers throw an exception or an error that doesn't get otherwise handled. */
|
||||
|
43
core/src/com/unciv/ui/audio/GameSounds.kt
Normal file
43
core/src/com/unciv/ui/audio/GameSounds.kt
Normal file
@ -0,0 +1,43 @@
|
||||
package com.unciv.ui.audio
|
||||
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.event.EventBus
|
||||
import com.unciv.logic.multiplayer.MultiplayerGameUpdated
|
||||
import com.unciv.logic.multiplayer.isUsersTurn
|
||||
import com.unciv.models.metadata.SettingsPropertyUncivSoundChanged
|
||||
|
||||
/**
|
||||
* Controls which sounds should be played when something happens while playing the game.
|
||||
*/
|
||||
object GameSounds {
|
||||
private val events = EventBus.EventReceiver()
|
||||
private val settings get() = UncivGame.Current.settings
|
||||
private val mpSettings get() = settings.multiplayer
|
||||
|
||||
/**
|
||||
* Has to be called for sounds to be played.
|
||||
*/
|
||||
fun init() {
|
||||
playSettingsSounds()
|
||||
playMultiplayerTurnNotification()
|
||||
}
|
||||
|
||||
private fun playSettingsSounds() {
|
||||
events.receive(SettingsPropertyUncivSoundChanged::class) {
|
||||
SoundPlayer.play(it.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun playMultiplayerTurnNotification() {
|
||||
events.receive(MultiplayerGameUpdated::class, { it.preview.isUsersTurn() }) {
|
||||
if (UncivGame.isDeepLinkedGameLoading()) return@receive // This means we already arrived here through a turn notification, no need to notify again
|
||||
val gameId = it.preview.gameId
|
||||
val sound = if (UncivGame.isCurrentGame(gameId)) {
|
||||
mpSettings.currentGameTurnNotificationSound
|
||||
} else {
|
||||
mpSettings.otherGameTurnNotificationSound
|
||||
}
|
||||
SoundPlayer.play(sound)
|
||||
}
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ import java.io.File
|
||||
* a handful of them in memory we should be able to get away with keeping them alive for the
|
||||
* app lifetime - and we do dispose them when the app is disposed.
|
||||
*/
|
||||
object Sounds {
|
||||
object SoundPlayer {
|
||||
@Suppress("EnumEntryName")
|
||||
private enum class SupportedExtensions { mp3, ogg, wav } // Per Gdx docs, no aac/m4a
|
||||
|
||||
@ -117,7 +117,7 @@ object Sounds {
|
||||
else GetSoundResult(soundMap[sound]!!, false)
|
||||
|
||||
// Not cached - try loading it
|
||||
val fileName = sound.value
|
||||
val fileName = sound.fileName
|
||||
var file: FileHandle? = null
|
||||
for ( (modFolder, extension) in getFolders().flatMap {
|
||||
// This is essentially a cross join. To operate on all combinations, we pack both lambda
|
||||
@ -134,12 +134,12 @@ object Sounds {
|
||||
|
||||
@Suppress("LiftReturnOrAssignment")
|
||||
if (file == null || !file.exists()) {
|
||||
debug("Sound %s not found!", sound.value)
|
||||
debug("Sound %s not found!", sound.fileName)
|
||||
// remember that the actual file is missing
|
||||
soundMap[sound] = null
|
||||
return null
|
||||
} else {
|
||||
debug("Sound %s loaded from %s", sound.value, file.path())
|
||||
debug("Sound %s loaded from %s", sound.fileName, file.path())
|
||||
val newSound = Gdx.audio.newSound(file)
|
||||
// Store Sound for reuse
|
||||
soundMap[sound] = newSound
|
||||
@ -147,7 +147,11 @@ object Sounds {
|
||||
}
|
||||
}
|
||||
|
||||
/** Find, cache and play a Sound
|
||||
/**
|
||||
* Find, cache and play a Sound.
|
||||
*
|
||||
* **Attention:** The [GameSounds] object has been set up to control playing all sounds of the game. Chances are that you shouldn't be calling this method
|
||||
* from anywhere but [GameSounds].
|
||||
*
|
||||
* Sources are mods from a loaded game, then mods marked as permanent audiovisual,
|
||||
* and lastly Unciv's own assets/sounds. Will fail silently if the sound file cannot be found.
|
@ -6,7 +6,10 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.city.CityFocus
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
class CitizenManagementTable(val cityScreen: CityScreen) : Table(BaseScreen.skin) {
|
||||
val city = cityScreen.city
|
||||
|
@ -8,7 +8,11 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.city.*
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.city.IConstruction
|
||||
import com.unciv.logic.city.INonPerpetualConstruction
|
||||
import com.unciv.logic.city.PerpetualConstruction
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.ruleset.Building
|
||||
@ -16,15 +20,29 @@ import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.audio.Sounds
|
||||
import com.unciv.ui.audio.SoundPlayer
|
||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.popup.closeAllPopups
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
||||
import com.unciv.ui.utils.extensions.addBorder
|
||||
import com.unciv.ui.utils.extensions.addCell
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.brighten
|
||||
import com.unciv.ui.utils.extensions.darken
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.getConsumesAmountString
|
||||
import com.unciv.ui.utils.extensions.isEnabled
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.packIfNeeded
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
@ -409,7 +427,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
|
||||
}
|
||||
cityScreen.stopPickTileForCreatesOneImprovement()
|
||||
|
||||
Sounds.play(getConstructionSound(construction))
|
||||
SoundPlayer.play(getConstructionSound(construction))
|
||||
|
||||
cityConstructions.addToQueue(construction.name)
|
||||
if (!construction.shouldBeDisplayed(cityConstructions)) // For buildings - unlike units which can be queued multiple times
|
||||
@ -533,7 +551,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
|
||||
stat: Stat = Stat.Gold,
|
||||
tile: TileInfo? = null
|
||||
) {
|
||||
Sounds.play(stat.purchaseSound)
|
||||
SoundPlayer.play(stat.purchaseSound)
|
||||
val city = cityScreen.city
|
||||
if (!city.cityConstructions.purchaseConstruction(construction.name, selectedQueueEntry, false, stat, tile)) {
|
||||
Popup(cityScreen).apply {
|
||||
|
@ -19,7 +19,16 @@ import com.unciv.ui.images.IconCircleGroup
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.popup.closeAllPopups
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.extensions.addBorder
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.darken
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import java.text.DecimalFormat
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
||||
|
@ -12,7 +12,12 @@ import com.unciv.ui.images.IconCircleGroup
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.overviewscreen.EmpireOverviewCategories
|
||||
import com.unciv.ui.overviewscreen.EmpireOverviewScreen
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.addSeparatorVertical
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
class CityReligionInfoTable(
|
||||
private val religionManager: CityInfoReligionManager,
|
||||
@ -67,7 +72,7 @@ class CityReligionInfoTable(
|
||||
private fun getIconAndLabel(religionName: String?) =
|
||||
getIconAndLabel(gameInfo.religions[religionName])
|
||||
private fun getIconAndLabel(religion: Religion?): Pair<String, String> {
|
||||
return if (religion == null) "Religion" to "None"
|
||||
return if (religion == null) "Religion" to "None"
|
||||
else religion.getIconName() to religion.getReligionDisplayName()
|
||||
}
|
||||
private fun linkedReligionIcon(iconName: String, religion: String?): IconCircleGroup {
|
||||
|
@ -19,7 +19,13 @@ import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.map.TileGroupMap
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.tilegroups.TileSetStrings
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ZoomableScrollPane
|
||||
import com.unciv.ui.utils.extensions.center
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.packIfNeeded
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
|
||||
class CityScreen(
|
||||
internal val city: CityInfo,
|
||||
|
@ -6,7 +6,8 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.popup.AskTextPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
/** Widget for the City Screen -
|
||||
* the panel at bottom center showing the city name and offering arrows to cycle through the cities. */
|
||||
|
@ -8,15 +8,20 @@ import com.unciv.models.UncivSound
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.audio.Sounds
|
||||
import com.unciv.ui.audio.SoundPlayer
|
||||
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||
import com.unciv.ui.civilopedia.FormattedLine.IconDisplay
|
||||
import com.unciv.ui.civilopedia.MarkupRenderer
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.popup.closeAllPopups
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
||||
import com.unciv.ui.utils.extensions.darken
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.isEnabled
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
||||
@ -91,7 +96,7 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
||||
}
|
||||
|
||||
/** Ask whether user wants to buy [selectedTile] for gold.
|
||||
*
|
||||
*
|
||||
* Used from onClick and keyboard dispatch, thus only minimal parameters are passed,
|
||||
* and it needs to do all checks and the sound as appropriate.
|
||||
*/
|
||||
@ -108,7 +113,7 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
||||
YesNoPopup(
|
||||
purchasePrompt,
|
||||
action = {
|
||||
Sounds.play(UncivSound.Coin)
|
||||
SoundPlayer.play(UncivSound.Coin)
|
||||
city.expansion.buyTile(selectedTile)
|
||||
// preselect the next tile on city screen rebuild so bulk buying can go faster
|
||||
UncivGame.Current.setScreen(CityScreen(city, initSelectedTile = city.expansion.chooseNewTileToOwn()))
|
||||
@ -142,4 +147,4 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
||||
}
|
||||
return statsTable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,13 @@ import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.colorFromRGB
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.round
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
@ -4,11 +4,11 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.tilegroups.TileGroup
|
||||
import com.unciv.ui.tilegroups.TileSetStrings
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.centerX
|
||||
import com.unciv.ui.utils.extensions.centerX
|
||||
|
||||
class CityTileGroup(private val city: CityInfo, tileInfo: TileInfo, tileSetStrings: TileSetStrings) : TileGroup(tileInfo,tileSetStrings) {
|
||||
|
||||
|
@ -13,7 +13,10 @@ import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.extensions.darken
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
|
||||
class ConstructionInfoTable(val cityScreen: CityScreen): Table() {
|
||||
private val selectedConstructionTable = Table()
|
||||
|
@ -6,9 +6,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.extensions.addBorder
|
||||
import com.unciv.ui.utils.extensions.addSeparatorVertical
|
||||
import com.unciv.ui.utils.extensions.darken
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
class SpecialistAllocationTable(val cityScreen: CityScreen) : Table(BaseScreen.skin) {
|
||||
val cityInfo = cityScreen.city
|
||||
|
@ -5,7 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.surroundWithCircle
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
|
||||
class YieldGroup : HorizontalGroup() {
|
||||
init {
|
||||
@ -56,4 +56,4 @@ class YieldGroup : HorizontalGroup() {
|
||||
table.pack()
|
||||
return table
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,11 @@ import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.tile.Terrain
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.tilegroups.TileGroup
|
||||
import com.unciv.ui.tilegroups.TileSetStrings
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.surroundWithCircle
|
||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||
import java.io.File
|
||||
|
||||
/** Encapsulates the knowledge on how to get an icon for each of the Civilopedia categories */
|
||||
@ -90,7 +90,7 @@ object CivilopediaImageGetters {
|
||||
val belief = { name: String, size: Float ->
|
||||
// Kludge until we decide how exactly to show Religions
|
||||
fun getInvertedCircledReligionIcon(iconName: String, size: Float) =
|
||||
ImageGetter.getCircledReligionIcon(iconName, size).apply {
|
||||
ImageGetter.getCircledReligionIcon(iconName, size).apply {
|
||||
circle.color = Color.WHITE
|
||||
actor.color = Color.BLACK
|
||||
}
|
||||
@ -108,7 +108,7 @@ object CivilopediaImageGetters {
|
||||
/** Enum used as keys for Civilopedia "pages" (categories).
|
||||
*
|
||||
* Note names are singular on purpose - a "link" allows both key and label
|
||||
* Order of values determines ordering of the categories in the Civilopedia top bar
|
||||
* Order of values determines ordering of the categories in the Civilopedia top bar
|
||||
*
|
||||
* @param label Translatable caption for the Civilopedia button
|
||||
*/
|
||||
|
@ -4,18 +4,27 @@ import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Button
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.SplitPane
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.ruleset.*
|
||||
import com.unciv.models.ruleset.Belief
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.unique.IHasUniques
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.images.IconTextButton
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
||||
import com.unciv.ui.utils.extensions.colorFromRGB
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
||||
/** Screen displaying the Civilopedia
|
||||
@ -299,7 +308,7 @@ class CivilopediaScreen(
|
||||
}
|
||||
|
||||
private fun navigateEntries(direction: Int) {
|
||||
//todo this is abusing a Map as Array - there must be a collection allowing both easy positional and associative access
|
||||
//todo this is abusing a Map as Array - there must be a collection allowing both easy positional and associative access
|
||||
val index = entryIndex.keys.indexOf(currentEntry)
|
||||
if (index < 0) return selectEntry(entryIndex.keys.first(), true)
|
||||
val newIndex = when (direction) {
|
||||
|
@ -12,11 +12,12 @@ import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.ruleset.unique.Unique
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.ui.civilopedia.MarkupRenderer.render
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.addSeparator
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.toLabel
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.utils.Log
|
||||
import kotlin.math.max
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.unciv.ui.crashhandling
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.unciv.ui.utils.wrapCrashHandlingUnit
|
||||
import com.unciv.UncivGame
|
||||
import kotlinx.coroutines.*
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.ThreadFactory
|
||||
@ -72,4 +72,47 @@ fun launchCrashHandling(name: String, runAsDaemon: Boolean = true,
|
||||
|
||||
private fun getCoroutineContext(runAsDaemon: Boolean): CoroutineScope {
|
||||
return if (runAsDaemon) CRASH_HANDLING_DAEMON_SCOPE else CRASH_HANDLING_SCOPE
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns a wrapped version of a function that safely crashes the game to [CrashScreen] if an exception or error is thrown.
|
||||
*
|
||||
* In case an exception or error is thrown, the return will be null. Therefore the return type is always nullable.
|
||||
*
|
||||
* The game loop, threading, and event systems already use this to wrap nearly everything that can happen during the lifespan of the Unciv application.
|
||||
*
|
||||
* Therefore, it usually shouldn't be necessary to manually use this. See the note at the top of [CrashScreen].kt for details.
|
||||
*
|
||||
* @param postToMainThread Whether the [CrashScreen] should be opened by posting a runnable to the main thread, instead of directly. Set this to true if the function is going to run on any thread other than the main loop.
|
||||
* @return Result from the function, or null if an exception is thrown.
|
||||
* */
|
||||
fun <R> (() -> R).wrapCrashHandling(
|
||||
postToMainThread: Boolean = false
|
||||
): () -> R?
|
||||
= {
|
||||
try {
|
||||
this()
|
||||
} catch (e: Throwable) {
|
||||
if (postToMainThread) {
|
||||
Gdx.app.postRunnable {
|
||||
UncivGame.Current.setScreen(CrashScreen(e))
|
||||
}
|
||||
} else UncivGame.Current.setScreen(CrashScreen(e))
|
||||
null
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns a wrapped a version of a Unit-returning function which safely crashes the game to [CrashScreen] if an exception or error is thrown.
|
||||
*
|
||||
* The game loop, threading, and event systems already use this to wrap nearly everything that can happen during the lifespan of the Unciv application.
|
||||
*
|
||||
* Therefore, it usually shouldn't be necessary to manually use this. See the note at the top of [CrashScreen].kt for details.
|
||||
*
|
||||
* @param postToMainThread Whether the [CrashScreen] should be opened by posting a runnable to the main thread, instead of directly. Set this to true if the function is going to run on any thread other than the main loop.
|
||||
* */
|
||||
fun (() -> Unit).wrapCrashHandlingUnit(
|
||||
postToMainThread: Boolean = false
|
||||
): () -> Unit {
|
||||
val wrappedReturning = this.wrapCrashHandling(postToMainThread)
|
||||
// Don't instantiate a new lambda every time the return get called.
|
||||
return { wrappedReturning() ?: Unit }
|
||||
}
|
||||
|
@ -13,7 +13,12 @@ import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.ui.images.IconTextButton
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.AutoScrollPane
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.extensions.addBorder
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.setFontSize
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.utils.Log
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
|
@ -5,7 +5,7 @@ import com.badlogic.gdx.graphics.g2d.Batch
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||
import com.badlogic.gdx.scenes.scene2d.Group
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.ui.utils.center
|
||||
import com.unciv.ui.utils.extensions.center
|
||||
|
||||
class IconCircleGroup(size: Float, val actor: Actor, resizeActor: Boolean = true, color: Color = Color.WHITE): Group(){
|
||||
val circle = ImageGetter.getCircle().apply {
|
||||
|
@ -8,7 +8,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.toLabel
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
/**
|
||||
* Translate a [String] and make a [Button] widget from it, with control over font size, font colour, an optional icon, and custom formatting.
|
||||
|
@ -25,6 +25,7 @@ import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.tilesets.TileSetCache
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.extensions.*
|
||||
import com.unciv.utils.debug
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.max
|
||||
|
@ -1,7 +1,12 @@
|
||||
package com.unciv.ui.mapeditor
|
||||
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.badlogic.gdx.scenes.scene2d.*
|
||||
import com.badlogic.gdx.scenes.scene2d.Action
|
||||
import com.badlogic.gdx.scenes.scene2d.EventListener
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent
|
||||
import com.badlogic.gdx.scenes.scene2d.InputListener
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.HexMath
|
||||
@ -12,8 +17,8 @@ import com.unciv.ui.tilegroups.TileGroup
|
||||
import com.unciv.ui.tilegroups.TileSetStrings
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ZoomableScrollPane
|
||||
import com.unciv.ui.utils.center
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.extensions.center
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
|
||||
|
||||
/**
|
||||
|
@ -6,7 +6,6 @@ import com.unciv.ui.newgamescreen.GameOptionsTable
|
||||
import com.unciv.ui.newgamescreen.IPreviousScreen
|
||||
import com.unciv.ui.newgamescreen.PlayerPickerTable
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.utils.*
|
||||
|
||||
/**
|
||||
* As of MapEditor V2, the editor no longer deals with GameParameters, **only** with MapParameters,
|
||||
|
@ -9,7 +9,11 @@ import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.ruleset.Nation
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.tile.*
|
||||
import com.unciv.models.ruleset.tile.ResourceType
|
||||
import com.unciv.models.ruleset.tile.Terrain
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.models.ruleset.tile.TileImprovement
|
||||
import com.unciv.models.ruleset.tile.TileResource
|
||||
import com.unciv.models.ruleset.unique.UniqueType
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
@ -18,7 +22,11 @@ import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.mapeditor.MapEditorEditTab.BrushHandlerType
|
||||
import com.unciv.ui.tilegroups.TileGroup
|
||||
import com.unciv.ui.tilegroups.TileSetStrings
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.extensions.center
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
internal interface IMapEditorEditSubTabs {
|
||||
fun isDisabled(): Boolean
|
||||
|
@ -15,7 +15,12 @@ import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.mapeditor.MapEditorOptionsTab.TileMatchFuzziness
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.UncivSlider
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.utils.Log
|
||||
|
||||
class MapEditorEditTab(
|
||||
|
@ -9,9 +9,9 @@ import com.unciv.logic.MapSaver
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.pad
|
||||
import com.unciv.ui.utils.toLabel
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.pad
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
class MapEditorFilesTable(
|
||||
initWidth: Float,
|
||||
@ -74,7 +74,7 @@ class MapEditorFilesTable(
|
||||
|
||||
var lastMod = ""
|
||||
for ((index, entry) in sortedFiles.withIndex()) {
|
||||
val (mod, mapFile) = entry
|
||||
val (mod, mapFile) = entry
|
||||
if (mod != lastMod) {
|
||||
// One header per Mod
|
||||
add(Table().apply {
|
||||
|
@ -15,7 +15,17 @@ import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.newgamescreen.MapParametersTable
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.isEnabled
|
||||
import com.unciv.ui.utils.extensions.onChange
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toCheckBox
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import com.unciv.utils.Log
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
|
@ -13,7 +13,13 @@ import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.AutoScrollPane
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.extensions.isEnabled
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import com.unciv.utils.Log
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
|
@ -10,8 +10,14 @@ import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.ui.newgamescreen.ModCheckboxTable
|
||||
import com.unciv.ui.newgamescreen.TranslatedSelectBox
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
||||
import com.unciv.ui.utils.extensions.isEnabled
|
||||
import com.unciv.ui.utils.extensions.onChange
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
|
||||
class MapEditorModsTab(
|
||||
private val editorScreen: MapEditorScreen
|
||||
|
@ -8,7 +8,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.unciv.logic.MapSaver
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.isEnabled
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toCheckBox
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
|
||||
class MapEditorOptionsTab(
|
||||
private val editorScreen: MapEditorScreen
|
||||
|
@ -13,7 +13,14 @@ import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.AutoScrollPane
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.extensions.isEnabled
|
||||
import com.unciv.ui.utils.extensions.onChange
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class MapEditorSaveTab(
|
||||
@ -123,4 +130,4 @@ class MapEditorSaveTab(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,12 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.MainMenuScreen
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.HexMath
|
||||
import com.unciv.logic.map.*
|
||||
import com.unciv.logic.map.MapParameters
|
||||
import com.unciv.logic.map.MapShape
|
||||
import com.unciv.logic.map.MapSize
|
||||
import com.unciv.logic.map.MapSizeNew
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.models.metadata.BaseRuleset
|
||||
import com.unciv.models.metadata.GameSetupInfo
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
@ -15,7 +20,8 @@ import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.tilegroups.TileGroup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.KeyCharAndCode
|
||||
import com.unciv.ui.worldscreen.ZoomButtonPair
|
||||
|
||||
|
||||
|
@ -15,10 +15,18 @@ import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||
import com.unciv.ui.civilopedia.FormattedLine
|
||||
import com.unciv.ui.civilopedia.MarkupRenderer
|
||||
import com.unciv.ui.civilopedia.FormattedLine.IconDisplay
|
||||
import com.unciv.ui.civilopedia.MarkupRenderer
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.TabbedPager
|
||||
import com.unciv.ui.utils.WrappableLabel
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.darken
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.pad
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
|
||||
class MapEditorViewTab(
|
||||
private val editorScreen: MapEditorScreen
|
||||
|
@ -8,7 +8,10 @@ import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import java.util.*
|
||||
|
||||
class AddFriendScreen(backScreen: ViewFriendsListScreen) : PickerScreen() {
|
||||
|
@ -7,11 +7,13 @@ import com.unciv.logic.IdChecker
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
import com.unciv.ui.multiplayer.MultiplayerHelpers
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import java.util.*
|
||||
|
||||
class AddMultiplayerGameScreen(backScreen: MultiplayerScreen) : PickerScreen() {
|
||||
|
@ -10,7 +10,10 @@ import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import java.util.*
|
||||
|
||||
class EditFriendScreen(selectedFriend: FriendList.Friend, backScreen: ViewFriendsListScreen) : PickerScreen() {
|
||||
|
@ -4,14 +4,17 @@ import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.unciv.logic.multiplayer.OnlineMultiplayerGame
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
import com.unciv.ui.multiplayer.MultiplayerHelpers
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
|
||||
/** Subscreen of MultiplayerScreen to edit and delete saves
|
||||
* backScreen is used for getting back to the MultiplayerScreen so it doesn't have to be created over and over again */
|
||||
|
@ -6,7 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.ui.newgamescreen.PlayerPickerTable
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
|
||||
class FriendPickerList(
|
||||
playerPicker: PlayerPickerTable,
|
||||
|
@ -17,13 +17,12 @@ import com.unciv.logic.multiplayer.MultiplayerGameUpdateEnded
|
||||
import com.unciv.logic.multiplayer.MultiplayerGameUpdateFailed
|
||||
import com.unciv.logic.multiplayer.MultiplayerGameUpdateStarted
|
||||
import com.unciv.logic.multiplayer.MultiplayerGameUpdateSucceeded
|
||||
import com.unciv.logic.multiplayer.MultiplayerGameUpdateUnchanged
|
||||
import com.unciv.logic.multiplayer.MultiplayerGameUpdated
|
||||
import com.unciv.logic.multiplayer.isUsersTurn
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.setSize
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.setSize
|
||||
|
||||
class GameList(
|
||||
onSelected: (String) -> Unit
|
||||
|
@ -2,8 +2,8 @@ package com.unciv.ui.multiplayer
|
||||
|
||||
import com.unciv.Constants
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.center
|
||||
import com.unciv.ui.utils.toLabel
|
||||
import com.unciv.ui.utils.extensions.center
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
class LoadDeepLinkScreen : BaseScreen() {
|
||||
init {
|
||||
|
@ -11,7 +11,8 @@ import com.unciv.ui.crashhandling.launchCrashHandling
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.toCheckBox
|
||||
import com.unciv.ui.utils.extensions.formatShort
|
||||
import com.unciv.ui.utils.extensions.toCheckBox
|
||||
import java.io.FileNotFoundException
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
@ -50,27 +51,15 @@ object MultiplayerHelpers {
|
||||
descriptionText.appendLine(message.tr())
|
||||
}
|
||||
val lastUpdate = multiplayerGame.lastUpdate
|
||||
descriptionText.appendLine("Last refresh: ${formattedElapsedTime(lastUpdate)} ago".tr())
|
||||
descriptionText.appendLine("Last refresh: [${Duration.between(lastUpdate, Instant.now()).formatShort()}] ago".tr())
|
||||
val preview = multiplayerGame.preview
|
||||
if (preview?.currentPlayer != null) {
|
||||
val currentTurnStartTime = Instant.ofEpochMilli(preview.currentTurnStartTime)
|
||||
descriptionText.appendLine("Current Turn: [${preview.currentPlayer}] since ${formattedElapsedTime(currentTurnStartTime)} ago".tr())
|
||||
descriptionText.appendLine("Current Turn: [${preview.currentPlayer}] since [${Duration.between(currentTurnStartTime, Instant.now()).formatShort()}] ago".tr())
|
||||
}
|
||||
return descriptionText
|
||||
}
|
||||
|
||||
private fun formattedElapsedTime(lastUpdate: Instant): String {
|
||||
val durationToNow = Duration.between(lastUpdate, Instant.now())
|
||||
val elapsedMinutes = durationToNow.toMinutes()
|
||||
if (elapsedMinutes < 120) return "[$elapsedMinutes] [Minutes]"
|
||||
val elapsedHours = durationToNow.toHours()
|
||||
if (elapsedHours < 48) {
|
||||
return "[${elapsedHours}] [Hours]"
|
||||
} else {
|
||||
return "[${durationToNow.toDays()}] [Days]"
|
||||
}
|
||||
}
|
||||
|
||||
fun showDropboxWarning(screen: BaseScreen) {
|
||||
if (!OnlineMultiplayer.usesDropbox() || UncivGame.Current.settings.multiplayer.hideDropboxWarning) return
|
||||
|
||||
|
@ -7,16 +7,14 @@ import com.unciv.logic.event.EventBus
|
||||
import com.unciv.logic.multiplayer.MultiplayerGameDeleted
|
||||
import com.unciv.logic.multiplayer.OnlineMultiplayerGame
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.multiplayer.GameList
|
||||
import com.unciv.ui.multiplayer.MultiplayerHelpers
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.disable
|
||||
import com.unciv.ui.utils.enable
|
||||
import com.unciv.ui.utils.onClick
|
||||
import com.unciv.ui.utils.toTextButton
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
||||
class MultiplayerScreen(previousScreen: BaseScreen) : PickerScreen() {
|
||||
|
@ -4,7 +4,11 @@ import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
||||
class ViewFriendsListScreen(previousScreen: BaseScreen) : PickerScreen() {
|
||||
|
@ -7,6 +7,7 @@ import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.multiplayer.FriendList
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.extensions.pad
|
||||
|
||||
class FriendTable(val friend: FriendList.Friend, width: Float, minHeight: Float)
|
||||
: Table() {
|
||||
@ -26,7 +27,7 @@ class FriendTable(val friend: FriendList.Friend, width: Float, minHeight: Float)
|
||||
friendDisplayLabel.wrap = true
|
||||
titleTable.add(friendDisplayLabel).width(friendDisplayNameMaxWidth)
|
||||
} else {
|
||||
titleTable.add(friendDisplayLabel).align(Align.center).pad(10f,0f)
|
||||
titleTable.add(friendDisplayLabel).align(Align.center).pad(10f, 0f)
|
||||
}
|
||||
|
||||
innerTable.add(titleTable).growX().fillY().row()
|
||||
|
@ -17,7 +17,11 @@ import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.multiplayer.MultiplayerHelpers
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.UncivSlider
|
||||
import com.unciv.ui.utils.extensions.onChange
|
||||
import com.unciv.ui.utils.extensions.toCheckBox
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
class GameOptionsTable(
|
||||
val previousScreen: IPreviousScreen,
|
||||
|
@ -11,8 +11,8 @@ import com.unciv.logic.map.MapType
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.onChange
|
||||
import com.unciv.ui.utils.toLabel
|
||||
import com.unciv.ui.utils.extensions.onChange
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
|
||||
class MapOptionsTable(private val newGameScreen: NewGameScreen): Table() {
|
||||
|
||||
|
@ -6,8 +6,21 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField.TextFieldFilter.DigitsOnlyFilter
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.map.*
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.logic.map.MapParameters
|
||||
import com.unciv.logic.map.MapResources
|
||||
import com.unciv.logic.map.MapShape
|
||||
import com.unciv.logic.map.MapSize
|
||||
import com.unciv.logic.map.MapSizeNew
|
||||
import com.unciv.logic.map.MapType
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.UncivSlider
|
||||
import com.unciv.ui.utils.extensions.onChange
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.pad
|
||||
import com.unciv.ui.utils.extensions.toCheckBox
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
|
||||
/** Table for editing [mapParameters]
|
||||
*
|
||||
|
@ -7,12 +7,16 @@ import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.extensions.onChange
|
||||
import com.unciv.ui.utils.extensions.pad
|
||||
import com.unciv.ui.utils.extensions.toCheckBox
|
||||
|
||||
/**
|
||||
* A widget containing one expander for extension mods.
|
||||
* A widget containing one expander for extension mods.
|
||||
* Manages compatibility checks, warns or prevents incompatibilities.
|
||||
*
|
||||
*
|
||||
* @param mods In/out set of active mods, modified in place
|
||||
* @param baseRuleset The selected base Ruleset //todo clarify
|
||||
* @param screen Parent screen, used only to show [ToastPopup]s
|
||||
@ -51,8 +55,8 @@ class ModCheckboxTable(
|
||||
}).padTop(padTop).growX().row()
|
||||
}
|
||||
}
|
||||
|
||||
fun setBaseRuleset(newBaseRuleset: String) { baseRuleset = newBaseRuleset }
|
||||
|
||||
fun setBaseRuleset(newBaseRuleset: String) { baseRuleset = newBaseRuleset }
|
||||
fun disableAllCheckboxes() {
|
||||
for (checkBox in extensionRulesetModButtons) {
|
||||
checkBox.isChecked = false
|
||||
|
@ -11,7 +11,9 @@ import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.ui.civilopedia.FormattedLine.IconDisplay
|
||||
import com.unciv.ui.civilopedia.MarkupRenderer
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.WrappableLabel
|
||||
import com.unciv.ui.utils.extensions.pad
|
||||
|
||||
// The ruleset also acts as a secondary parameter to determine if this is the right or self side of the player picker
|
||||
class NationTable(val nation: Nation, width: Float, minHeight: Float, ruleset: Ruleset? = null)
|
||||
|
@ -8,7 +8,10 @@ import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup
|
||||
import com.badlogic.gdx.utils.Array
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.*
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.GameStarter
|
||||
import com.unciv.logic.IdChecker
|
||||
import com.unciv.logic.MapSaver
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.map.MapType
|
||||
import com.unciv.logic.multiplayer.OnlineMultiplayer
|
||||
@ -23,7 +26,16 @@ import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.popup.ToastPopup
|
||||
import com.unciv.ui.popup.YesNoPopup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.BaseScreen
|
||||
import com.unciv.ui.utils.ExpanderTab
|
||||
import com.unciv.ui.utils.extensions.addSeparator
|
||||
import com.unciv.ui.utils.extensions.addSeparatorVertical
|
||||
import com.unciv.ui.utils.extensions.disable
|
||||
import com.unciv.ui.utils.extensions.enable
|
||||
import com.unciv.ui.utils.extensions.onClick
|
||||
import com.unciv.ui.utils.extensions.pad
|
||||
import com.unciv.ui.utils.extensions.toLabel
|
||||
import com.unciv.ui.utils.extensions.toTextButton
|
||||
import java.net.URL
|
||||
import java.util.*
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
@ -210,10 +222,9 @@ class NewGameScreen(
|
||||
}
|
||||
|
||||
private fun checkConnectionToMultiplayerServer(): Boolean {
|
||||
val isDropbox = UncivGame.Current.settings.multiplayer.server == Constants.dropboxMultiplayerServer
|
||||
return try {
|
||||
val multiplayerServer = UncivGame.Current.settings.multiplayer.server
|
||||
val u = URL(if (isDropbox) "https://content.dropboxapi.com" else multiplayerServer)
|
||||
val u = URL(if (OnlineMultiplayer.usesDropbox()) "https://content.dropboxapi.com" else multiplayerServer)
|
||||
val con = u.openConnection()
|
||||
con.connectTimeout = 3000
|
||||
con.connect()
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.unciv.ui.newgamescreen
|
||||
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Group
|
||||
@ -28,7 +27,9 @@ import com.unciv.ui.pickerscreens.PickerPane
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.popup.Popup
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.extensions.*
|
||||
import java.util.*
|
||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||
|
||||
/**
|
||||
* This [Table] is used to pick or edit players information for new game creation.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user