mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-21 10:25:10 -04:00
Merge e520134d248827cb34010ddb785b65baec7bf927 into d51ef24c205b6b05330b3c4d7ce79c402db44447
This commit is contained in:
commit
81258e56b6
BIN
android/Images.ConstructionIcons/UnitIcons/Great Admiral.png
Normal file
BIN
android/Images.ConstructionIcons/UnitIcons/Great Admiral.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 906 KiB After Width: | Height: | Size: 904 KiB |
@ -9,6 +9,7 @@
|
||||
"Cannot build [Settler] units <when below [-10] [Happiness]>",
|
||||
"Rebel units may spawn <when below [-20] [Happiness]>",
|
||||
"[-1] Sight <for [Embarked] units>",
|
||||
"Enables [Great Admiral] units to enter ocean tiles",
|
||||
|
||||
// TODO: Implement the uniques below
|
||||
// "[+20]% [Culture] [in all cities] <during a golden age>",
|
||||
|
@ -1658,6 +1658,17 @@
|
||||
"Great Person - [War]", "Unbuildable", "Uncapturable"],
|
||||
"movement": 5
|
||||
},
|
||||
{
|
||||
"name": "Great Admiral",
|
||||
"unitType": "Civilian Water",
|
||||
"uniques": [
|
||||
"[Every adjacent [{Friendly} {Water}] unit] heals [100] HP <by consuming this unit>",
|
||||
"[+15]% Strength bonus for [{Military} {Water}] units within [2] tiles",
|
||||
"Can be earned through combat",
|
||||
"Is part of Great Person group [Admiral]",
|
||||
"Great Person - [War]", "Unbuildable", "Uncapturable"],
|
||||
"movement": 4
|
||||
},
|
||||
|
||||
/* Religious units */
|
||||
|
||||
|
@ -19,7 +19,7 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
||||
override fun isDefeated(): Boolean = unit.health <= 0
|
||||
override fun isInvisible(to: Civilization): Boolean = unit.isInvisible(to)
|
||||
override fun canAttack(): Boolean = unit.canAttack()
|
||||
override fun matchesFilter(filter: String, multiFilter: Boolean) = unit.matchesFilter(filter, multiFilter)
|
||||
override fun matchesFilter(filter: String, multiFilter: Boolean) = unit.matchesFilter(filter, multiFilter=multiFilter)
|
||||
override fun getAttackSound() = unit.baseUnit.attackSound.let {
|
||||
if (it == null) UncivSound.Click else UncivSound(it)
|
||||
}
|
||||
|
@ -607,12 +607,12 @@ class MapUnit : IsPartOfGameInfoSerialization {
|
||||
|
||||
/** Implements [UniqueParameterType.MapUnitFilter][com.unciv.models.ruleset.unique.UniqueParameterType.MapUnitFilter] */
|
||||
@Readonly
|
||||
fun matchesFilter(filter: String, multiFilter: Boolean = true): Boolean {
|
||||
return if (multiFilter) MultiFilter.multiFilter(filter, ::matchesSingleFilter) else matchesSingleFilter(filter)
|
||||
}
|
||||
fun matchesFilter(filter: String, state: GameContext? = cache.state, multiFilter: Boolean = true): Boolean =
|
||||
if (multiFilter) MultiFilter.multiFilter(filter, { matchesSingleFilter(it, state) })
|
||||
else matchesSingleFilter(filter, state)
|
||||
|
||||
@Readonly
|
||||
private fun matchesSingleFilter(filter: String): Boolean {
|
||||
private fun matchesSingleFilter(filter: String, state: GameContext? = cache.state): Boolean {
|
||||
return when (filter) {
|
||||
Constants.wounded, "wounded units" -> health < 100
|
||||
Constants.barbarians, "Barbarian" -> civ.isBarbarian
|
||||
@ -620,9 +620,9 @@ class MapUnit : IsPartOfGameInfoSerialization {
|
||||
Constants.embarked -> isEmbarked()
|
||||
"Non-City" -> true
|
||||
else -> {
|
||||
if (baseUnit.matchesFilter(filter, cache.state, false)) return true
|
||||
if (civ.matchesFilter(filter, cache.state, false)) return true
|
||||
if (nonUnitUniquesMap.hasUnique(filter, cache.state)) return true
|
||||
if (baseUnit.matchesFilter(filter, state, false)) return true
|
||||
if (civ.matchesFilter(filter, state, false)) return true
|
||||
if (nonUnitUniquesMap.hasUnique(filter, if (state == null) cache.state else state)) return true
|
||||
if (promotions.promotions.contains(filter)) return true
|
||||
if (hasStatus(filter)) return true
|
||||
return false
|
||||
|
@ -12,6 +12,7 @@ import com.unciv.models.ruleset.unique.UniqueParameterType.Companion.guessTypeFo
|
||||
import com.unciv.models.ruleset.validation.Suppression
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.SubStat
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.models.translations.TranslationFileWriter
|
||||
import yairm210.purity.annotations.Pure
|
||||
import yairm210.purity.annotations.Readonly
|
||||
@ -86,7 +87,7 @@ enum class UniqueParameterType(
|
||||
|
||||
// todo potentially remove if OneTimeRevealSpecificMapTiles changes
|
||||
KeywordAll("'all'", "All", severityDefault = UniqueType.UniqueParameterErrorSeverity.RulesetInvariant) {
|
||||
override val staticKnownValues = Constants.all
|
||||
override val staticKnownValues = Constants.all
|
||||
},
|
||||
|
||||
/** Implemented by [ICombatant.matchesCategory][com.unciv.logic.battle.ICombatant.matchesFilter] */
|
||||
@ -595,9 +596,19 @@ enum class UniqueParameterType(
|
||||
override val staticKnownValues = setOf("Cost", "Strength")
|
||||
},
|
||||
|
||||
|
||||
UnitTriggerTarget("unitTriggerTarget", Constants.thisUnit, "`${Constants.thisUnit}` or `${Constants.targetUnit}`") {
|
||||
UnitTriggerTarget("unitTriggerTarget", Constants.thisUnit, "`${Constants.thisUnit}`, `${Constants.targetUnit}`, or `Every adjacent [mapUnitFilter] unit`") {
|
||||
override val staticKnownValues = setOf(Constants.thisUnit, Constants.targetUnit)
|
||||
|
||||
override fun isKnownValue(parameterText: String, ruleset: Ruleset): Boolean {
|
||||
if (parameterText in staticKnownValues) return true
|
||||
// Every adjacent [mapUnitFilter] unit
|
||||
if (parameterText.startsWith("Every adjacent [") && parameterText.endsWith("] unit")) {
|
||||
val params = parameterText.getPlaceholderParameters()
|
||||
return MultiFilter.multiFilter(params[0], { MapUnitFilter.isKnownValue(it, ruleset) }, true)
|
||||
}
|
||||
return false
|
||||
}
|
||||
override fun getErrorSeverity(parameterText: String, ruleset: Ruleset) = getErrorSeverityForFilter(parameterText, ruleset)
|
||||
},
|
||||
|
||||
/** Mod declarative compatibility: Define Mod relations by their name. */
|
||||
|
@ -29,8 +29,10 @@ import com.unciv.models.ruleset.BeliefType
|
||||
import com.unciv.models.ruleset.Event
|
||||
import com.unciv.models.ruleset.tile.TerrainType
|
||||
import com.unciv.models.ruleset.tile.TileResource
|
||||
import com.unciv.models.ruleset.unique.UniqueParameterType
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.getPlaceholderParameters
|
||||
import com.unciv.models.UncivSound
|
||||
import com.unciv.models.translations.fillPlaceholders
|
||||
import com.unciv.models.translations.hasPlaceholderParameters
|
||||
@ -91,7 +93,8 @@ object UniqueTriggerActivation {
|
||||
unit: MapUnit? = null,
|
||||
tile: Tile? = city?.getCenterTile() ?: unit?.currentTile,
|
||||
notification: String? = null,
|
||||
triggerNotificationText: String? = null
|
||||
triggerNotificationText: String? = null,
|
||||
unitTriggerableIteration: Boolean = false
|
||||
): (()->Boolean)? {
|
||||
|
||||
val relevantCity by lazy {
|
||||
@ -121,6 +124,26 @@ object UniqueTriggerActivation {
|
||||
else Random(-550) // Very random indeed
|
||||
val ruleset = civInfo.gameInfo.ruleset
|
||||
|
||||
// Allow iterating through all unit targets, if needed.
|
||||
if (unique.type?.targetTypes?.contains(UniqueTarget.UnitTriggerable) == true && !unitTriggerableIteration && tile != null &&
|
||||
!UniqueParameterType.UnitTriggerTarget.staticKnownValues.contains(unique.params[0])) {
|
||||
// Every adjacent [mapUnitFilter] unit
|
||||
val triggerFunctions = tile.getTilesInDistance(1) // Adjacent
|
||||
.flatMap { it.getUnits() }
|
||||
.filter {
|
||||
val mapUnitFilter = unique.params[0]?.getPlaceholderParameters()?.firstOrNull()
|
||||
if (mapUnitFilter != null) it.matchesFilter(mapUnitFilter, gameContext) else false
|
||||
}
|
||||
.mapNotNull { getTriggerFunction(unique, civInfo, city, it, it.getTile(), notification, triggerNotificationText, true) }
|
||||
if (triggerFunctions.none()) return null
|
||||
return {
|
||||
for (triggerFunction in triggerFunctions) {
|
||||
triggerFunction.invoke()
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
when (unique.type) {
|
||||
UniqueType.TriggerEvent -> {
|
||||
val event = ruleset.events[unique.params[0]] ?: return null
|
||||
|
@ -258,7 +258,7 @@ object UnitActionsFromUniques {
|
||||
)
|
||||
}
|
||||
UniqueType.TriggerEvent -> unique.params[0]
|
||||
else -> unique.text.removeConditionals()
|
||||
else -> unique.text.removeConditionals().tr()
|
||||
}
|
||||
val title = UnitActionModifiers.actionTextWithSideEffects(baseTitle, unique, unit)
|
||||
|
||||
|
@ -160,6 +160,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
|
||||
- [General](https://thenounproject.com/icon/general-933566) By anbileru adaleru for Great General
|
||||
- [Religion](https://thenounproject.com/icon/preach-53064) by Bruno Gätjens González adapted for Missionary
|
||||
- [invisibility cloak ](https://thenounproject.com/term/invisibility-cloak/1419648/) by Locad for Inquisitor
|
||||
- [Anchor](https://thenounproject.com/icon/anchor-7764100/) by M. Adebadal for Great Admiral
|
||||
|
||||
### Units - AbsoluteUnits unitset images
|
||||
|
||||
|
@ -3964,7 +3964,7 @@ There is a conversion affecting dashes and leading/trailing blanks. Please make
|
||||
*[tech]: The name of any tech.
|
||||
*[terrainFeature]: The name of any terrain that is a terrain feature according to the json file.
|
||||
*[tileFilter]: Anything that can be used either in an improvementFilter or in a terrainFilter can be used here, plus 'unimproved'
|
||||
*[unitTriggerTarget]: `This Unit` or `Target Unit`.
|
||||
*[unitTriggerTarget]: `This Unit`, `Target Unit`, or `Every adjacent [mapUnitFilter] unit`.
|
||||
*[unitType]: Can be 'Land', 'Water', 'Air', any unit type, a filtering Unique on a unit type, or a multi-filter of these.
|
||||
*[validationWarning]: Suppresses one specific Ruleset validation warning. This can specify the full text verbatim including correct upper/lower case, or it can be a wildcard case-insensitive simple pattern starting and ending in an asterisk ('*'). If the suppression unique is used within an object or as modifier (not ModOptions), the wildcard symbols can be omitted, as selectivity is better due to the limited scope.
|
||||
*[victoryType]: The name of any victory type: 'Cultural', 'Diplomatic', 'Domination', 'Scientific', 'Time' or one of your mod's VictoryTypes.json names.
|
Loading…
x
Reference in New Issue
Block a user