Added unit symbols for Strength, Ranged Strength, Range and Movement as 'emojis'
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 825 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 880 KiB After Width: | Height: | Size: 869 KiB |
Before Width: | Height: | Size: 481 KiB After Width: | Height: | Size: 484 KiB |
@ -9,6 +9,7 @@ import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.UncivGameParameters
|
||||
import com.unciv.logic.GameSaver
|
||||
import com.unciv.ui.utils.ORIGINAL_FONT_SIZE
|
||||
import java.io.File
|
||||
|
||||
class AndroidLauncher : AndroidApplication() {
|
||||
@ -28,7 +29,7 @@ class AndroidLauncher : AndroidApplication() {
|
||||
version = BuildConfig.VERSION_NAME,
|
||||
crashReportSender = CrashReportSenderAndroid(this),
|
||||
exitEvent = this::finish,
|
||||
fontImplementation = NativeFontAndroid(45)
|
||||
fontImplementation = NativeFontAndroid(ORIGINAL_FONT_SIZE.toInt())
|
||||
)
|
||||
val game = UncivGame ( androidParameters )
|
||||
initialize(game, config)
|
||||
|
@ -6,6 +6,7 @@ import com.unciv.logic.civilization.CityStateType
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.models.translations.Translations
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import com.unciv.ui.utils.colorFromRGB
|
||||
|
||||
enum class VictoryType {
|
||||
@ -142,13 +143,13 @@ class Nation : INamed {
|
||||
if (unit.cost != originalUnit.cost)
|
||||
textList += " {Cost} " + "[${unit.cost}] vs [${originalUnit.cost}]".tr()
|
||||
if (unit.strength != originalUnit.strength)
|
||||
textList += " {Strength} " + "[${unit.strength}] vs [${originalUnit.strength}]".tr()
|
||||
textList += " ${Fonts.strength} " + "[${unit.strength}] vs [${originalUnit.strength}]".tr()
|
||||
if (unit.rangedStrength != originalUnit.rangedStrength)
|
||||
textList += " {Ranged strength} " + "[${unit.rangedStrength}] vs [${originalUnit.rangedStrength}]".tr()
|
||||
textList += " ${Fonts.rangedStrength} " + "[${unit.rangedStrength}] vs [${originalUnit.rangedStrength}]".tr()
|
||||
if (unit.range != originalUnit.range)
|
||||
textList += " {Range} " + "[${unit.range}] vs [${originalUnit.range}]".tr()
|
||||
textList += " ${Fonts.range} " + "[${unit.range}] vs [${originalUnit.range}]".tr()
|
||||
if (unit.movement != originalUnit.movement)
|
||||
textList += " {Movement} " + "[${unit.movement}] vs [${originalUnit.movement}]".tr()
|
||||
textList += " ${Fonts.movement} " + "[${unit.movement}] vs [${originalUnit.movement}]".tr()
|
||||
if (originalUnit.requiredResource != null && unit.requiredResource == null)
|
||||
textList += " " + "[${originalUnit.requiredResource}] not required".tr()
|
||||
for (unique in unit.uniques.filterNot { it in originalUnit.uniques })
|
||||
|
@ -10,6 +10,7 @@ import com.unciv.models.ruleset.Unique
|
||||
import com.unciv.models.translations.Translations
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.models.stats.INamed
|
||||
import com.unciv.ui.utils.Fonts
|
||||
import kotlin.math.pow
|
||||
|
||||
// This is BaseUnit because Unit is already a base Kotlin class and to avoid mixing the two up
|
||||
@ -45,9 +46,9 @@ class BaseUnit : INamed, IConstruction {
|
||||
infoList+= Translations.translateBonusOrPenalty(unique)
|
||||
for(promotion in promotions)
|
||||
infoList += promotion.tr()
|
||||
if(strength!=0) infoList += "{Strength}: $strength".tr()
|
||||
if(rangedStrength!=0) infoList += "{Ranged strength}: $rangedStrength".tr()
|
||||
if(movement!=2) infoList+="{Movement}: $movement".tr()
|
||||
if(strength!=0) infoList += "$strength${Fonts.strength}"
|
||||
if(rangedStrength!=0) infoList += "$rangedStrength${Fonts.rangedStrength}"
|
||||
if(movement!=2) infoList+="$movement${Fonts.movement}"
|
||||
return infoList.joinToString()
|
||||
}
|
||||
|
||||
@ -61,12 +62,12 @@ class BaseUnit : INamed, IConstruction {
|
||||
if(upgradesTo!=null) sb.appendln("Upgrades to [$upgradesTo]".tr())
|
||||
if(obsoleteTech!=null) sb.appendln("Obsolete with [$obsoleteTech]".tr())
|
||||
}
|
||||
if(strength!=0){
|
||||
sb.append("{Strength}: $strength".tr())
|
||||
if(rangedStrength!=0) sb.append(", {Ranged strength}: $rangedStrength".tr())
|
||||
if(rangedStrength!=0) sb.append(", {Range}: $range".tr())
|
||||
sb.appendln()
|
||||
if(strength!=0) {
|
||||
sb.append("$strength${Fonts.strength}, ")
|
||||
if (rangedStrength != 0) sb.append("$rangedStrength${Fonts.rangedStrength}, ")
|
||||
if (rangedStrength != 0) sb.append("$range${Fonts.range}, ")
|
||||
}
|
||||
sb.appendln("$movement${Fonts.movement}")
|
||||
|
||||
for(unique in uniques)
|
||||
sb.appendln(Translations.translateBonusOrPenalty(unique))
|
||||
@ -76,7 +77,6 @@ class BaseUnit : INamed, IConstruction {
|
||||
sb.appendln(promotions.joinToString(", ", " ") { it.tr() })
|
||||
}
|
||||
|
||||
sb.appendln("{Movement}: $movement".tr())
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,7 @@ class MultiplayerScreen(previousScreen: CameraStageBaseScreen) : PickerScreen()
|
||||
multiplayerGameList[game.gameId] = gameSaveFile
|
||||
|
||||
if (isUsersTurn(game)) {
|
||||
gameTable.add(ImageGetter.getNationIndicator(game.currentPlayerCiv.nation, 45f))
|
||||
gameTable.add(ImageGetter.getNationIndicator(game.currentPlayerCiv.nation, 50f))
|
||||
} else {
|
||||
gameTable.add()
|
||||
}
|
||||
|
@ -298,9 +298,9 @@ class EmpireOverviewScreen(private var viewingPlayer:CivilizationInfo, defaultPa
|
||||
val table=Table(skin).apply { defaults().pad(5f) }
|
||||
table.add("Name".tr())
|
||||
table.add("Action".tr())
|
||||
table.add("Strength".tr())
|
||||
table.add("Ranged strength".tr())
|
||||
table.add("Movement".tr())
|
||||
table.add(Fonts.strength)
|
||||
table.add(Fonts.rangedStrength)
|
||||
table.add(Fonts.movement.toString())
|
||||
table.add("Closest city".tr())
|
||||
table.add("Promotions".tr())
|
||||
table.add("Health".tr())
|
||||
|
@ -12,24 +12,28 @@ import com.unciv.ui.utils.*
|
||||
/** This is the class that holds the 4 columns of the offers (ours/theirs/ offered/available) in trade */
|
||||
class OfferColumnsTable(val tradeLogic: TradeLogic, val screen: DiplomacyScreen, val onChange: ()->Unit): Table(CameraStageBaseScreen.skin) {
|
||||
|
||||
fun addOffer(offer:TradeOffer, offerList:TradeOffersList, correspondingOfferList:TradeOffersList){
|
||||
fun addOffer(offer: TradeOffer, offerList: TradeOffersList, correspondingOfferList: TradeOffersList) {
|
||||
offerList.add(offer.copy())
|
||||
if(offer.type==TradeType.Treaty) correspondingOfferList.add(offer.copy())
|
||||
if (offer.type == TradeType.Treaty) correspondingOfferList.add(offer.copy())
|
||||
onChange()
|
||||
}
|
||||
|
||||
val ourAvailableOffersTable = OffersListScroll {
|
||||
if(it.type==TradeType.Gold) openGoldSelectionPopup(it, tradeLogic.currentTrade.ourOffers, tradeLogic.ourCivilization)
|
||||
else addOffer(it,tradeLogic.currentTrade.ourOffers, tradeLogic.currentTrade.theirOffers) }
|
||||
if (it.type == TradeType.Gold) openGoldSelectionPopup(it, tradeLogic.currentTrade.ourOffers, tradeLogic.ourCivilization)
|
||||
else addOffer(it, tradeLogic.currentTrade.ourOffers, tradeLogic.currentTrade.theirOffers)
|
||||
}
|
||||
val ourOffersTable = OffersListScroll {
|
||||
if (it.type==TradeType.Gold) openGoldSelectionPopup(it, tradeLogic.currentTrade.ourOffers, tradeLogic.ourCivilization)
|
||||
else addOffer(it.copy(amount=-it.amount),tradeLogic.currentTrade.ourOffers, tradeLogic.currentTrade.theirOffers) }
|
||||
if (it.type == TradeType.Gold) openGoldSelectionPopup(it, tradeLogic.currentTrade.ourOffers, tradeLogic.ourCivilization)
|
||||
else addOffer(it.copy(amount = -it.amount), tradeLogic.currentTrade.ourOffers, tradeLogic.currentTrade.theirOffers)
|
||||
}
|
||||
val theirOffersTable = OffersListScroll {
|
||||
if (it.type==TradeType.Gold) openGoldSelectionPopup(it, tradeLogic.currentTrade.theirOffers, tradeLogic.otherCivilization)
|
||||
else addOffer(it.copy(amount=-it.amount),tradeLogic.currentTrade.theirOffers, tradeLogic.currentTrade.ourOffers) }
|
||||
if (it.type == TradeType.Gold) openGoldSelectionPopup(it, tradeLogic.currentTrade.theirOffers, tradeLogic.otherCivilization)
|
||||
else addOffer(it.copy(amount = -it.amount), tradeLogic.currentTrade.theirOffers, tradeLogic.currentTrade.ourOffers)
|
||||
}
|
||||
val theirAvailableOffersTable = OffersListScroll {
|
||||
if (it.type==TradeType.Gold) openGoldSelectionPopup(it, tradeLogic.currentTrade.theirOffers, tradeLogic.otherCivilization)
|
||||
else addOffer(it,tradeLogic.currentTrade.theirOffers, tradeLogic.currentTrade.ourOffers) }
|
||||
if (it.type == TradeType.Gold) openGoldSelectionPopup(it, tradeLogic.currentTrade.theirOffers, tradeLogic.otherCivilization)
|
||||
else addOffer(it, tradeLogic.currentTrade.theirOffers, tradeLogic.currentTrade.ourOffers)
|
||||
}
|
||||
|
||||
init {
|
||||
defaults().pad(5f)
|
||||
@ -38,15 +42,15 @@ class OfferColumnsTable(val tradeLogic: TradeLogic, val screen: DiplomacyScreen,
|
||||
add("Our items".tr())
|
||||
add("[${tradeLogic.otherCivilization.civName}]'s items".tr()).row()
|
||||
|
||||
add(ourAvailableOffersTable).size(columnWidth,screen.stage.height/2)
|
||||
add(theirAvailableOffersTable).size(columnWidth,screen.stage.height/2).row()
|
||||
add(ourAvailableOffersTable).size(columnWidth, screen.stage.height / 2)
|
||||
add(theirAvailableOffersTable).size(columnWidth, screen.stage.height / 2).row()
|
||||
|
||||
addSeparator().height(2f)
|
||||
|
||||
add("Our trade offer".tr())
|
||||
add("[${tradeLogic.otherCivilization.civName}]'s trade offer".tr()).row()
|
||||
add(ourOffersTable).size(columnWidth,screen.stage.height/5)
|
||||
add(theirOffersTable).size(columnWidth,screen.stage.height/5)
|
||||
add(ourOffersTable).size(columnWidth, screen.stage.height / 5)
|
||||
add(theirOffersTable).size(columnWidth, screen.stage.height / 5)
|
||||
pack()
|
||||
update()
|
||||
}
|
||||
@ -61,7 +65,7 @@ class OfferColumnsTable(val tradeLogic: TradeLogic, val screen: DiplomacyScreen,
|
||||
}
|
||||
|
||||
|
||||
fun openGoldSelectionPopup(offer: TradeOffer, ourOffers: TradeOffersList, offeringCiv:CivilizationInfo) {
|
||||
fun openGoldSelectionPopup(offer: TradeOffer, ourOffers: TradeOffersList, offeringCiv: CivilizationInfo) {
|
||||
val selectionPopup = Popup(screen)
|
||||
val existingGoldOffer = ourOffers.firstOrNull { it.type == TradeType.Gold }
|
||||
if (existingGoldOffer != null)
|
||||
|
@ -78,14 +78,14 @@ open class CameraStageBaseScreen : Screen {
|
||||
addRegions(TextureAtlas("skin/flat-earth-ui.atlas"))
|
||||
load(Gdx.files.internal("skin/flat-earth-ui.json"))
|
||||
}
|
||||
skin.get(TextButton.TextButtonStyle::class.java).font = Fonts.font.apply { data.setScale(20/45f) }
|
||||
skin.get(CheckBox.CheckBoxStyle::class.java).font= Fonts.font.apply { data.setScale(20/45f) }
|
||||
skin.get(CheckBox.CheckBoxStyle::class.java).fontColor= Color.WHITE
|
||||
skin.get(Label.LabelStyle::class.java).font= Fonts.font.apply { data.setScale(18/45f) }
|
||||
skin.get(Label.LabelStyle::class.java).fontColor= Color.WHITE
|
||||
skin.get(TextField.TextFieldStyle::class.java).font = Fonts.font.apply { data.setScale(18/45f) }
|
||||
skin.get(SelectBox.SelectBoxStyle::class.java).font = Fonts.font.apply { data.setScale(20/45f) }
|
||||
skin.get(SelectBox.SelectBoxStyle::class.java).listStyle.font = Fonts.font.apply { data.setScale(20/45f) }
|
||||
skin.get(TextButton.TextButtonStyle::class.java).font = Fonts.font.apply { data.setScale(20 / ORIGINAL_FONT_SIZE) }
|
||||
skin.get(CheckBox.CheckBoxStyle::class.java).font = Fonts.font.apply { data.setScale(20 / ORIGINAL_FONT_SIZE) }
|
||||
skin.get(CheckBox.CheckBoxStyle::class.java).fontColor = Color.WHITE
|
||||
skin.get(Label.LabelStyle::class.java).font = Fonts.font.apply { data.setScale(18 / ORIGINAL_FONT_SIZE) }
|
||||
skin.get(Label.LabelStyle::class.java).fontColor = Color.WHITE
|
||||
skin.get(TextField.TextFieldStyle::class.java).font = Fonts.font.apply { data.setScale(18 / ORIGINAL_FONT_SIZE) }
|
||||
skin.get(SelectBox.SelectBoxStyle::class.java).font = Fonts.font.apply { data.setScale(20 / ORIGINAL_FONT_SIZE) }
|
||||
skin.get(SelectBox.SelectBoxStyle::class.java).listStyle.font = Fonts.font.apply { data.setScale(20 / ORIGINAL_FONT_SIZE) }
|
||||
skin
|
||||
}
|
||||
internal var batch: Batch = SpriteBatch()
|
||||
@ -241,6 +241,11 @@ fun String.toTextButton() = TextButton(this.tr(), CameraStageBaseScreen.skin)
|
||||
fun String.toLabel() = Label(this.tr(),CameraStageBaseScreen.skin)
|
||||
fun Int.toLabel() = this.toString().toLabel()
|
||||
|
||||
/** All text is originally rendered in 50px, and thn scaled to fit the size of the text we need now.
|
||||
* This has several advantages: It means we only render each character once (good for both runtime and RAM),
|
||||
* AND it means that our 'custom' emojis only need to be once size (50px) and they'll be rescaled for what's needed. */
|
||||
const val ORIGINAL_FONT_SIZE = 50f
|
||||
|
||||
// We don't want to use setFontSize and setFontColor because they set the font,
|
||||
// which means we need to rebuild the font cache which means more memory allocation.
|
||||
fun String.toLabel(fontColor:Color= Color.WHITE, fontSize:Int=18): Label {
|
||||
@ -250,15 +255,15 @@ fun String.toLabel(fontColor:Color= Color.WHITE, fontSize:Int=18): Label {
|
||||
labelStyle.fontColor = fontColor
|
||||
if (fontSize != 18) labelStyle.font = Fonts.font
|
||||
}
|
||||
return Label(this.tr(),labelStyle).apply { setFontScale(fontSize/45f) }
|
||||
return Label(this.tr(), labelStyle).apply { setFontScale(fontSize/ORIGINAL_FONT_SIZE) }
|
||||
}
|
||||
|
||||
|
||||
fun Label.setFontColor(color:Color): Label {style=Label.LabelStyle(style).apply { fontColor=color }; return this}
|
||||
fun Label.setFontColor(color:Color): Label { style=Label.LabelStyle(style).apply { fontColor=color }; return this }
|
||||
|
||||
fun Label.setFontSize(size:Int): Label {
|
||||
style = Label.LabelStyle(style)
|
||||
style.font = Fonts.font
|
||||
style = style // because we need it to call the SetStyle function. Yuk, I know.
|
||||
return this.apply { setFontScale(size/45f) } // for chaining
|
||||
return this.apply { setFontScale(size/ORIGINAL_FONT_SIZE) } // for chaining
|
||||
}
|
@ -59,8 +59,10 @@ class NativeBitmapFontData(val fontImplementation: NativeFontImplementation) : B
|
||||
if(ch == '\uD83D' || ch == '\uD83C' ) return Glyph() // This is the 'first character' of an emoji - empty space
|
||||
val charPixmap =
|
||||
when (ch) {
|
||||
Fonts.food[1] -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Food").region)
|
||||
Fonts.gold[1] -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("StatIcons/Gold").region)
|
||||
Fonts.strength[1] -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("StatIcons/Strength").region)
|
||||
Fonts.rangedStrength[1] -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("StatIcons/RangedStrength").region)
|
||||
Fonts.range[1] -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("StatIcons/Range").region)
|
||||
Fonts.movement -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("StatIcons/Movement").region)
|
||||
Fonts.turn -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Turn").region)
|
||||
else -> fontImplementation.getCharPixmap(ch)
|
||||
}
|
||||
@ -136,4 +138,8 @@ object Fonts {
|
||||
const val food = "\uD83C\uDF4E"
|
||||
const val gold = "\uD83D\uDCB0"
|
||||
const val turn = '⏳'
|
||||
const val strength = "\uD83D\uDCAA"
|
||||
const val rangedStrength = "\uD83C\uDFF9"
|
||||
const val movement = '➡'
|
||||
const val range = "\uD83D\uDCCF"
|
||||
}
|
||||
|
@ -117,8 +117,8 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
|
||||
|
||||
addSeparator().pad(0f)
|
||||
|
||||
add("{Strength}: ".tr()+attacker.getAttackingStrength())
|
||||
add("{Strength}: ".tr()+defender.getDefendingStrength()).row()
|
||||
add(attacker.getAttackingStrength().toString()+Fonts.strength)
|
||||
add(defender.getDefendingStrength().toString()+Fonts.strength).row()
|
||||
|
||||
val attackerModifiers =
|
||||
BattleDamage.getAttackModifiers(attacker,null,defender).map {
|
||||
|
@ -11,6 +11,7 @@ import com.badlogic.gdx.tools.texturepacker.TexturePacker
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.UncivGameParameters
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.ORIGINAL_FONT_SIZE
|
||||
import io.ktor.application.call
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.request.receiveText
|
||||
@ -46,7 +47,7 @@ internal object DesktopLauncher {
|
||||
versionFromJar,
|
||||
exitEvent = { exitProcess(0) },
|
||||
cancelDiscordEvent = { discordTimer?.cancel() },
|
||||
fontImplementation = NativeFontDesktop(45)
|
||||
fontImplementation = NativeFontDesktop(ORIGINAL_FONT_SIZE.toInt())
|
||||
)
|
||||
|
||||
val game = UncivGame ( desktopParameters )
|
||||
|