Add a Play Sound unique (#13867)

This commit is contained in:
Rob Loach 2025-08-30 13:48:28 -04:00 committed by GitHub
parent fced164c0b
commit 640a5b17bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 55 additions and 10 deletions

View File

@ -2,7 +2,10 @@
{ {
"name": "discover cultural artifacts", "name": "discover cultural artifacts",
"notification": "We have discovered cultural artifacts in the ruins! (+20 culture)", "notification": "We have discovered cultural artifacts in the ruins! (+20 culture)",
"uniques": ["Gain [20] [Culture] <(modified by game speed)>"], "uniques": [
"Gain [20] [Culture] <(modified by game speed)>",
"Play [policy] sound"
],
"color": "#cf8ff7" "color": "#cf8ff7"
}, },
{ {
@ -14,24 +17,36 @@
{ {
"name": "squatters wishing to settle under your rule", "name": "squatters wishing to settle under your rule",
"notification": "A [Settler] has joined us!", "notification": "A [Settler] has joined us!",
"uniques": ["Free [Settler] found in the ruins", "Unavailable <on [Prince] difficulty or higher>"], "uniques": [
"Free [Settler] found in the ruins", "Unavailable <on [Prince] difficulty or higher>",
"Play [wagon] sound"
],
"excludedDifficulties": ["Warlord","Prince","King","Emperor","Immortal","Deity"] "excludedDifficulties": ["Warlord","Prince","King","Emperor","Immortal","Deity"]
}, },
{ {
"name": "your exploring unit receives training", "name": "your exploring unit receives training",
"notification": "An ancient tribe trained us in their ways of combat!", "notification": "An ancient tribe trained us in their ways of combat!",
"uniques": ["[This Unit] gains [10] XP", "Only available <after turn number [10]>"] "uniques": [
"[This Unit] gains [10] XP", "Only available <after turn number [10]>",
"Play [promote] sound"
]
}, },
{ {
"name": "survivors (adds population to a city)", "name": "survivors (adds population to a city)",
"notification": "We have found survivors in the ruins! Population added to [cityName].", "notification": "We have found survivors in the ruins! Population added to [cityName].",
"uniques": ["[+1] population in a random city"], // This can't be easily added to cityFilter, as it is non-deterministic "uniques": [
"color": "#81c784" "[+1] population in a random city", // This can't be easily added to cityFilter, as it is non-deterministic
"Play [wagon] sound"
],
"color": "#81c784"
}, },
{ {
"name": "a stash of gold", "name": "a stash of gold",
"notification": "", // trigger notification only "notification": "", // trigger notification only
"uniques": ["Gain [50]-[100] [Gold] <(modified by game speed)>"], "uniques": [
"Gain [50]-[100] [Gold] <(modified by game speed)>",
"Play [coin] sound"
],
"color": "#ffeb7f" "color": "#ffeb7f"
}, },
{ {
@ -58,14 +73,20 @@
{ {
"name": "discover holy symbols", "name": "discover holy symbols",
"notification": "We have found holy symbols in the ruins, giving us a deeper understanding of religion! (+[faithAmount] Faith)", "notification": "We have found holy symbols in the ruins, giving us a deeper understanding of religion! (+[faithAmount] Faith)",
"uniques": ["Only available <when religion is enabled>", "Gain enough Faith for a Pantheon", "Only available <before founding a Pantheon>", "Only available <after turn number [20]>"], "uniques": [
"Only available <when religion is enabled>", "Gain enough Faith for a Pantheon", "Only available <before founding a Pantheon>", "Only available <after turn number [20]>",
"Play [choir] sound"
],
"color": "#CDDDF4" "color": "#CDDDF4"
}, },
{ {
"name": "an ancient prophecy", "name": "an ancient prophecy",
"notification": "We have found an ancient prophecy in the ruins, greatly increasing our spiritual connection! (+[faithAmount] Faith)", "notification": "We have found an ancient prophecy in the ruins, greatly increasing our spiritual connection! (+[faithAmount] Faith)",
"uniques": ["Only available <when religion is enabled>", "Gain enough Faith for [33]% of a Great Prophet", "Unavailable <after generating a Great Prophet>", "uniques": [
"Only available <after founding a Pantheon>", "Only available <after turn number [20]>"], "Only available <when religion is enabled>", "Gain enough Faith for [33]% of a Great Prophet", "Unavailable <after generating a Great Prophet>",
"Only available <after founding a Pantheon>", "Only available <after turn number [20]>",
"Play [choir] sound"
],
"color": "#CDDDF4" "color": "#CDDDF4"
} }
] ]

View File

@ -31,10 +31,12 @@ import com.unciv.models.ruleset.tile.TerrainType
import com.unciv.models.ruleset.tile.TileResource import com.unciv.models.ruleset.tile.TileResource
import com.unciv.models.stats.Stat import com.unciv.models.stats.Stat
import com.unciv.models.stats.Stats import com.unciv.models.stats.Stats
import com.unciv.models.UncivSound
import com.unciv.models.translations.fillPlaceholders import com.unciv.models.translations.fillPlaceholders
import com.unciv.models.translations.hasPlaceholderParameters import com.unciv.models.translations.hasPlaceholderParameters
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsUpgrade import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsUpgrade
import com.unciv.ui.audio.SoundPlayer
import com.unciv.utils.addToMapOfSets import com.unciv.utils.addToMapOfSets
import com.unciv.utils.randomWeighted import com.unciv.utils.randomWeighted
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -143,6 +145,17 @@ object UniqueTriggerActivation {
true true
} }
UniqueType.PlaySound -> {
val soundName = unique.params[0]
if (soundName.isEmpty()) return null
var sound = UncivSound(soundName)
SoundPlayer.get(sound) ?: return null
return {
SoundPlayer.play(sound)
true
}
}
UniqueType.OneTimeFreeUnit -> { UniqueType.OneTimeFreeUnit -> {
val unitName = unique.params[0] val unitName = unique.params[0]
val baseUnit = ruleset.units[unitName] ?: return null val baseUnit = ruleset.units[unitName] ?: return null

View File

@ -878,6 +878,8 @@ enum class UniqueType(
FreeSpecificBuildings("Provides a [buildingName] in your first [positiveAmount] cities for free", UniqueTarget.Triggerable), // used in Policy FreeSpecificBuildings("Provides a [buildingName] in your first [positiveAmount] cities for free", UniqueTarget.Triggerable), // used in Policy
TriggerEvent("Triggers a [event] event", UniqueTarget.Triggerable), TriggerEvent("Triggers a [event] event", UniqueTarget.Triggerable),
MarkTutorialComplete("Mark tutorial [comment] complete", UniqueTarget.Triggerable, flags = UniqueFlag.setOfHiddenNoConditionals), MarkTutorialComplete("Mark tutorial [comment] complete", UniqueTarget.Triggerable, flags = UniqueFlag.setOfHiddenNoConditionals),
PlaySound("Play [comment] sound", UniqueTarget.Triggerable, flags = UniqueFlag.setOfHiddenToUsers,
docDescription = "See [Images and Audio](Images-and-Audio.md#sounds) for a list of available sounds."),
//endregion //endregion

View File

@ -232,6 +232,15 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Triggerable Applicable to: Triggerable
??? example "Play [comment] sound"
See [Images and Audio](Images-and-Audio.md#sounds) for a list of available sounds.
Example: "Play [comment] sound"
This unique is automatically hidden from users.
Applicable to: Triggerable
??? example "Suppress warning [validationWarning]" ??? example "Suppress warning [validationWarning]"
Allows suppressing specific validation warnings. Errors, deprecation warnings, or warnings about untyped and non-filtering uniques should be heeded, not suppressed, and are therefore not accepted. Note that this can be used in ModOptions, in the uniques a warning is about, or as modifier on the unique triggering a warning - but you still need to be specific. Even in the modifier case you will need to specify a sufficiently selective portion of the warning text as parameter. Allows suppressing specific validation warnings. Errors, deprecation warnings, or warnings about untyped and non-filtering uniques should be heeded, not suppressed, and are therefore not accepted. Note that this can be used in ModOptions, in the uniques a warning is about, or as modifier on the unique triggering a warning - but you still need to be specific. Even in the modifier case you will need to specify a sufficiently selective portion of the warning text as parameter.