Units/Buildings can now be given optional Portraits to be displayed instead of flags. (#8107)

* Units can now be given optional Portraits to be displayed everywhere (except world map) instead of unit Flags.

* Add section to wiki for adding Unit Portraits

* Generify portrait functions

* Small nitpicks fixed

* Reverted one change

* Fix docs

* Fix docs

Co-authored-by: tunerzinc@gmail.com <vfylfhby>
This commit is contained in:
vegeta1k95 2022-12-11 21:58:11 +01:00 committed by GitHub
parent 154c083d3f
commit a134242487
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 467 additions and 448 deletions

View File

@ -309,7 +309,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
table.defaults().pad(2f).minWidth(40f)
if (isFirstConstructionOfItsKind) table.add(getProgressBar(constructionName)).minWidth(5f)
else table.add().minWidth(5f)
table.add(ImageGetter.getConstructionImage(constructionName).surroundWithCircle(40f)).padRight(10f)
table.add(ImageGetter.getPortraitImage(constructionName, 40f)).padRight(10f)
table.add(text.toLabel()).expandX().fillX().left()
if (constructionQueueIndex > 0) table.add(getRaisePriorityButton(constructionQueueIndex, constructionName, city)).right()
@ -362,7 +362,7 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
}
pickConstructionButton.add(getProgressBar(construction.name)).padRight(5f)
pickConstructionButton.add(ImageGetter.getConstructionImage(construction.name).surroundWithCircle(40f)).padRight(10f)
pickConstructionButton.add(ImageGetter.getPortraitImage(construction.name, 40f)).padRight(10f)
pickConstructionButton.add(constructionButtonDTO.buttonText.toLabel()).expandX().fillX()
if (!cannotAddConstructionToQueue(construction, cityScreen.city, cityScreen.city.cityConstructions)) {

View File

@ -120,7 +120,7 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
}
private fun addBuildingInfo(building: Building, destinationTable: Table) {
val icon = ImageGetter.getConstructionImage(building.name).surroundWithCircle(30f)
val icon = ImageGetter.getPortraitImage(building.name, 30f)
val isFree = building.name in cityScreen.city.civInfo.civConstructions.getFreeBuildings(cityScreen.city.id)
val displayName = if (isFree) "{${building.name}} ({Free})" else building.name
val buildingNameAndIconTable = ExpanderTab(

View File

@ -56,7 +56,7 @@ class ConstructionInfoTable(val cityScreen: CityScreen): Table() {
selectedConstructionTable.run {
pad(10f)
add(ImageGetter.getConstructionImage(construction.name).surroundWithCircle(50f))
add(ImageGetter.getPortraitImage(construction.name, 50f))
.pad(5f)
var buildingText = construction.name.tr()

View File

@ -52,8 +52,7 @@ object CivilopediaImageGetters {
}
val construction = { name: String, size: Float ->
ImageGetter.getConstructionImage(name)
.surroundWithCircle(size)
ImageGetter.getPortraitImage(name, size)
}
val improvement = { name: String, size: Float ->
ImageGetter.getImprovementIcon(name, size)

View File

@ -252,11 +252,24 @@ object ImageGetter {
return iconGroup
}
fun getConstructionImage(construction: String): Image {
if (ruleset.buildings.containsKey(construction)) return getImage("BuildingIcons/$construction")
if (ruleset.units.containsKey(construction)) return getUnitIcon(construction)
if (construction == "Nothing") return getImage("OtherIcons/Sleep")
return getStatIcon(construction)
fun getPortraitImage(construction: String, size: Float): Group {
if (ruleset.buildings.containsKey(construction)) {
val buildingPortraitLocation = "BuildingPortraits/$construction"
return if (imageExists(buildingPortraitLocation)) {
getImage(buildingPortraitLocation).toGroup(size)
} else
getImage("BuildingIcons/$construction").surroundWithCircle(size)
}
if (ruleset.units.containsKey(construction)) {
val unitPortraitLocation = "UnitPortraits/$construction"
return if (imageExists(unitPortraitLocation)) {
getImage(unitPortraitLocation).toGroup(size)
} else
getUnitIcon(construction).surroundWithCircle(size)
}
if (construction == "Nothing")
return getImage("OtherIcons/Sleep").surroundWithCircle(size)
return getStatIcon(construction).surroundWithCircle(size)
}
fun getPromotionIcon(promotionName: String, size: Float = 30f): Actor {

View File

@ -194,7 +194,7 @@ class CityOverviewTab(
val construction = city.cityConstructions.currentConstructionFromQueue
if (construction.isNotEmpty()) {
cityInfoTableDetails.add(ImageGetter.getConstructionImage(construction).surroundWithCircle(iconSize*0.8f)).padRight(paddingHorz)
cityInfoTableDetails.add(ImageGetter.getPortraitImage(construction, iconSize*0.8f)).padRight(paddingHorz)
} else {
cityInfoTableDetails.add()
}

View File

@ -64,15 +64,14 @@ class TechButton(techName:String, private val techManager: TechManager, isWorldS
val tech = ruleset.technologies[techName]!!
for (unit in tech.getEnabledUnits(ruleset, techManager.civInfo))
techEnabledIcons.add(ImageGetter.getConstructionImage(unit.name).surroundWithCircle(techIconSize))
techEnabledIcons.add(ImageGetter.getPortraitImage(unit.name, techIconSize))
for (building in tech.getEnabledBuildings(ruleset, techManager.civInfo))
techEnabledIcons.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(techIconSize))
techEnabledIcons.add(ImageGetter.getPortraitImage(building.name, techIconSize))
for (obj in tech.getObsoletedObjects(ruleset, techManager.civInfo)) {
val obsoletedIcon = when (obj) {
is Building -> ImageGetter.getConstructionImage(obj.name)
.surroundWithCircle(techIconSize)
is Building -> ImageGetter.getPortraitImage(obj.name, techIconSize)
is TileResource -> ImageGetter.getResourceImage(obj.name, techIconSize)
is TileImprovement -> ImageGetter.getImprovementIcon(obj.name, techIconSize)
else -> continue

View File

@ -383,19 +383,9 @@ class CityButton(val city: CityInfo, private val tileGroup: WorldTileGroup): Tab
val groupHeight = 25f
val groupWidth = if (cityCurrentConstruction is PerpetualConstruction) 15f else 40f
group.setSize(groupWidth, groupHeight)
val circle = ImageGetter.getCircle()
circle.setSize(25f, 25f)
val constructionImage = ImageGetter.getConstructionImage(cityConstructions.currentConstructionFromQueue)
constructionImage.setSize(18f, 18f)
val constructionImage = ImageGetter.getPortraitImage(cityConstructions.currentConstructionFromQueue, 25f)
constructionImage.centerY(group)
constructionImage.x = group.width - constructionImage.width
// center the circle on the production image
circle.x = constructionImage.x + (constructionImage.width - circle.width) / 2
circle.y = constructionImage.y + (constructionImage.height - circle.height) / 2
group.addActor(circle)
group.addActor(constructionImage)
val secondaryColor = cityConstructions.cityInfo.civInfo.nation.getInnerColor()

View File

@ -494,3 +494,13 @@ fun WidgetGroup.packIfNeeded(): WidgetGroup {
/** @return `true` if the screen is narrower than 4:3 landscape */
fun Stage.isNarrowerThan4to3() = viewport.screenHeight * 4 > viewport.screenWidth * 3
/** Wraps and returns an image in a [Group] of a given size*/
fun Image.toGroup(size: Float): Group {
return Group().apply {
setSize(size, size)
this@toGroup.setSize(size, size)
this@toGroup.center(this)
this@toGroup.setOrigin(Align.center)
addActor(this@toGroup) }
}

View File

@ -207,7 +207,7 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu
.row()
}
} else { // Fallback
add(ImageGetter.getConstructionImage(wonder.name).surroundWithCircle(100f)).pad(20f).row()
add(ImageGetter.getPortraitImage(wonder.name, 100f)).pad(20f).row()
}
val centerTable = Table()

View File

@ -41,6 +41,14 @@ These work best if they are square, between 100x100 and 256x256 pixels, and incl
For example, [here](https://github.com/yairm210/Unciv-leader-portrait-mod-example) is mod showing how to add leader portraits, which can complement the base game.
### Adding Unit and Building Portraits
The base game uses flat icons, colored to fit the civilization's flag colors, to denote units both on the map and in other UI elements. A mod can supply "Portraits" - static images that will remain uncolored - by adding their images to `/Images/UnitPortraits/` and `/Images/BuildingPortraits/`, which will be used in all UI elements except for the world map. The file name must correspond exactly with the unit/building name as defined in Units.json and Buildings.json, or they will be ignored.
These work best if they are full RGB square, between 100x100 and 256x256 pixels, and include some transparent border within that area.
For example, [here](https://github.com/vegeta1k95/Civ-5-Icons) is mod showing how to add unit portraits, which can complement the base game.
## Sounds
Standard values are below. The sounds themselves can be found [here](/sounds).

File diff suppressed because it is too large Load Diff