Skip to content

Commit

Permalink
Units/Buildings can now be given optional Portraits to be displayed i…
Browse files Browse the repository at this point in the history
…nstead 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: [email protected] <vfylfhby>
  • Loading branch information
vegeta1k95 authored Dec 11, 2022
1 parent 154c083 commit a134242
Show file tree
Hide file tree
Showing 12 changed files with 486 additions and 467 deletions.
4 changes: 2 additions & 2 deletions core/src/com/unciv/ui/cityscreen/CityConstructionsTable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/com/unciv/ui/cityscreen/CityInfoTable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion core/src/com/unciv/ui/cityscreen/ConstructionInfoTable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
3 changes: 1 addition & 2 deletions core/src/com/unciv/ui/civilopedia/CivilopediaCategories.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 18 additions & 5 deletions core/src/com/unciv/ui/images/ImageGetter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion core/src/com/unciv/ui/overviewscreen/CityOverviewTable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
7 changes: 3 additions & 4 deletions core/src/com/unciv/ui/pickerscreens/TechButton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 1 addition & 11 deletions core/src/com/unciv/ui/tilegroups/CityButton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
10 changes: 10 additions & 0 deletions core/src/com/unciv/ui/utils/extensions/Scene2dExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
}
2 changes: 1 addition & 1 deletion core/src/com/unciv/ui/worldscreen/AlertPopup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
8 changes: 8 additions & 0 deletions docs/Modders/Images-and-Audio.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
Loading

0 comments on commit a134242

Please sign in to comment.