mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 13:55:54 -04:00
First attempt at making Unciv Android-TV-compatible
This commit is contained in:
parent
07cee7e679
commit
0feb9bdefc
@ -6,12 +6,17 @@
|
|||||||
<uses-sdk/>
|
<uses-sdk/>
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<!-- See https://developer.android.com/training/tv/start/start -->
|
||||||
|
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||||
|
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@drawable/uncivicon2"
|
android:icon="@drawable/uncivicon2"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:isGame="true"
|
android:isGame="true"
|
||||||
|
android:appCategory="game"
|
||||||
|
android:banner="@drawable/banner"
|
||||||
android:theme="@style/GdxTheme" >
|
android:theme="@style/GdxTheme" >
|
||||||
<activity
|
<activity
|
||||||
android:name="com.unciv.app.AndroidLauncher"
|
android:name="com.unciv.app.AndroidLauncher"
|
||||||
@ -25,6 +30,19 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.unciv.app.AndroidTvLauncher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/GdxTheme">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</activity>
|
||||||
<receiver android:name=".CopyToClipboardReceiver" android:exported="false" />
|
<receiver android:name=".CopyToClipboardReceiver" android:exported="false" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
BIN
android/res/drawable-xhdpi/banner.png
Normal file
BIN
android/res/drawable-xhdpi/banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
@ -13,7 +13,7 @@ import com.unciv.logic.GameSaver
|
|||||||
import com.unciv.ui.utils.ORIGINAL_FONT_SIZE
|
import com.unciv.ui.utils.ORIGINAL_FONT_SIZE
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class AndroidLauncher : AndroidApplication() {
|
open class AndroidLauncher : AndroidApplication() {
|
||||||
private var customSaveLocationHelper: CustomSaveLocationHelperAndroid? = null
|
private var customSaveLocationHelper: CustomSaveLocationHelperAndroid? = null
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -88,3 +88,5 @@ class AndroidLauncher : AndroidApplication() {
|
|||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AndroidTvLauncher:AndroidLauncher()
|
@ -61,15 +61,14 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
private val diplomacyButtonHolder = Table()
|
private val diplomacyButtonHolder = Table()
|
||||||
private val fogOfWarButton = createFogOfWarButton()
|
private val fogOfWarButton = createFogOfWarButton()
|
||||||
private val nextTurnButton = createNextTurnButton()
|
private val nextTurnButton = createNextTurnButton()
|
||||||
private var nextTurnAction:()->Unit= {}
|
private var nextTurnAction: () -> Unit = {}
|
||||||
private val tutorialTaskTable = Table().apply { background=ImageGetter.getBackground(ImageGetter.getBlue().lerp(Color.BLACK, 0.5f)) }
|
private val tutorialTaskTable = Table().apply { background = ImageGetter.getBackground(ImageGetter.getBlue().lerp(Color.BLACK, 0.5f)) }
|
||||||
|
|
||||||
private val notificationsScroll: NotificationsScroll
|
private val notificationsScroll: NotificationsScroll
|
||||||
var shouldUpdate = false
|
var shouldUpdate = false
|
||||||
|
|
||||||
|
|
||||||
private var backButtonListener : InputListener
|
private var backButtonListener: InputListener
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -78,13 +77,13 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
|
|
||||||
notificationsScroll = NotificationsScroll(this)
|
notificationsScroll = NotificationsScroll(this)
|
||||||
// notifications are right-aligned, they take up only as much space as necessary.
|
// notifications are right-aligned, they take up only as much space as necessary.
|
||||||
notificationsScroll.width = stage.width/2
|
notificationsScroll.width = stage.width / 2
|
||||||
|
|
||||||
minimapWrapper.x = stage.width - minimapWrapper.width
|
minimapWrapper.x = stage.width - minimapWrapper.width
|
||||||
|
|
||||||
mapHolder.addTiles()
|
mapHolder.addTiles()
|
||||||
|
|
||||||
techButtonHolder.touchable=Touchable.enabled
|
techButtonHolder.touchable = Touchable.enabled
|
||||||
techButtonHolder.onClick(UncivSound.Paper) {
|
techButtonHolder.onClick(UncivSound.Paper) {
|
||||||
game.setScreen(TechPickerScreen(viewingCiv))
|
game.setScreen(TechPickerScreen(viewingCiv))
|
||||||
}
|
}
|
||||||
@ -94,7 +93,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
fogOfWarButton.setPosition(10f, topBar.y - fogOfWarButton.height - 10f)
|
fogOfWarButton.setPosition(10f, topBar.y - fogOfWarButton.height - 10f)
|
||||||
|
|
||||||
// Don't show policies until they become relevant
|
// Don't show policies until they become relevant
|
||||||
if(viewingCiv.policies.adoptedPolicies.isNotEmpty() || viewingCiv.policies.canAdoptPolicy()) {
|
if (viewingCiv.policies.adoptedPolicies.isNotEmpty() || viewingCiv.policies.canAdoptPolicy()) {
|
||||||
val policyScreenButton = Button(skin)
|
val policyScreenButton = Button(skin)
|
||||||
policyScreenButton.add(ImageGetter.getImage("PolicyIcons/Constitution")).size(30f).pad(15f)
|
policyScreenButton.add(ImageGetter.getImage("PolicyIcons/Constitution")).size(30f).pad(15f)
|
||||||
policyScreenButton.onClick { game.setScreen(PolicyPickerScreen(this)) }
|
policyScreenButton.onClick { game.setScreen(PolicyPickerScreen(this)) }
|
||||||
@ -116,8 +115,8 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
stage.addActor(diplomacyButtonHolder)
|
stage.addActor(diplomacyButtonHolder)
|
||||||
stage.addActor(bottomUnitTable)
|
stage.addActor(bottomUnitTable)
|
||||||
stage.addActor(bottomTileInfoTable)
|
stage.addActor(bottomTileInfoTable)
|
||||||
battleTable.width = stage.width/3
|
battleTable.width = stage.width / 3
|
||||||
battleTable.x = stage.width/3
|
battleTable.x = stage.width / 3
|
||||||
stage.addActor(battleTable)
|
stage.addActor(battleTable)
|
||||||
|
|
||||||
stage.addActor(unitActionsTable)
|
stage.addActor(unitActionsTable)
|
||||||
@ -133,28 +132,28 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
|
|
||||||
// Don't select unit and change selectedCiv when centering as spectator
|
// Don't select unit and change selectedCiv when centering as spectator
|
||||||
if (viewingCiv.isSpectator())
|
if (viewingCiv.isSpectator())
|
||||||
mapHolder.setCenterPosition(tileToCenterOn,true, false)
|
mapHolder.setCenterPosition(tileToCenterOn, true, false)
|
||||||
else
|
else
|
||||||
mapHolder.setCenterPosition(tileToCenterOn,true, true)
|
mapHolder.setCenterPosition(tileToCenterOn, true, true)
|
||||||
|
|
||||||
|
|
||||||
if(gameInfo.gameParameters.isOnlineMultiplayer && !gameInfo.isUpToDate)
|
if (gameInfo.gameParameters.isOnlineMultiplayer && !gameInfo.isUpToDate)
|
||||||
isPlayersTurn = false // until we're up to date, don't let the player do anything
|
isPlayersTurn = false // until we're up to date, don't let the player do anything
|
||||||
|
|
||||||
if(gameInfo.gameParameters.isOnlineMultiplayer && !isPlayersTurn) {
|
if (gameInfo.gameParameters.isOnlineMultiplayer && !isPlayersTurn) {
|
||||||
// restart the timer
|
// restart the timer
|
||||||
stopMultiPlayerRefresher()
|
stopMultiPlayerRefresher()
|
||||||
// isDaemon = true, in order to not block the app closing
|
// isDaemon = true, in order to not block the app closing
|
||||||
multiPlayerRefresher = Timer("multiPlayerRefresh", true).apply {
|
multiPlayerRefresher = Timer("multiPlayerRefresh", true).apply {
|
||||||
schedule(object : TimerTask() { //todo maybe not use timer for web request, from timer docs "Timer tasks should complete quickly."
|
schedule(object : TimerTask() { //todo maybe not use timer for web request, from timer docs "Timer tasks should complete quickly."
|
||||||
override fun run() { loadLatestMultiplayerState() }
|
override fun run() {
|
||||||
|
loadLatestMultiplayerState()
|
||||||
|
}
|
||||||
}, 0, 10000) // 10 seconds
|
}, 0, 10000) // 10 seconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tutorialController.allTutorialsShowedCallback = {
|
tutorialController.allTutorialsShowedCallback = { shouldUpdate = true }
|
||||||
shouldUpdate = true
|
|
||||||
}
|
|
||||||
|
|
||||||
backButtonListener = onBackButtonClicked { backButtonAndESCHandler() }
|
backButtonListener = onBackButtonClicked { backButtonAndESCHandler() }
|
||||||
|
|
||||||
@ -173,63 +172,63 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun cleanupKeyDispatcher() {
|
private fun cleanupKeyDispatcher() {
|
||||||
val delKeys = keyPressDispatcher.keys.filter { it!=' ' && it!='n' }
|
val delKeys = keyPressDispatcher.keys.filter { it != ' ' && it != 'n' }
|
||||||
delKeys.forEach { keyPressDispatcher.remove(it) }
|
delKeys.forEach { keyPressDispatcher.remove(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addKeyboardListener() {
|
private fun addKeyboardListener() {
|
||||||
stage.addListener(
|
stage.addListener(
|
||||||
object : InputListener() {
|
object : InputListener() {
|
||||||
private val pressedKeys = mutableSetOf<Int>()
|
private val pressedKeys = mutableSetOf<Int>()
|
||||||
private var infiniteAction : RepeatAction? = null
|
private var infiniteAction: RepeatAction? = null
|
||||||
private val amountToMove = 30 / mapHolder.scaleX
|
private val amountToMove = 30 / mapHolder.scaleX
|
||||||
private val ALLOWED_KEYS = setOf(Input.Keys.W,Input.Keys.S,Input.Keys.A,Input.Keys.D,
|
private val ALLOWED_KEYS = setOf(Input.Keys.W, Input.Keys.S, Input.Keys.A, Input.Keys.D,
|
||||||
Input.Keys.UP, Input.Keys.DOWN, Input.Keys.LEFT, Input.Keys.RIGHT )
|
Input.Keys.UP, Input.Keys.DOWN, Input.Keys.LEFT, Input.Keys.RIGHT)
|
||||||
|
|
||||||
|
|
||||||
override fun keyDown(event: InputEvent?, keycode: Int): Boolean {
|
override fun keyDown(event: InputEvent?, keycode: Int): Boolean {
|
||||||
if (keycode !in ALLOWED_KEYS) return false
|
if (keycode !in ALLOWED_KEYS) return false
|
||||||
|
|
||||||
pressedKeys.add(keycode)
|
pressedKeys.add(keycode)
|
||||||
if (infiniteAction == null) {
|
if (infiniteAction == null) {
|
||||||
// create a copy of the action, because removeAction() will destroy this instance
|
// create a copy of the action, because removeAction() will destroy this instance
|
||||||
infiniteAction = Actions.forever(Actions.delay(0.05f, Actions.run { whileKeyPressedLoop() }))
|
infiniteAction = Actions.forever(Actions.delay(0.05f, Actions.run { whileKeyPressedLoop() }))
|
||||||
mapHolder.addAction(infiniteAction)
|
mapHolder.addAction(infiniteAction)
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun whileKeyPressedLoop() {
|
|
||||||
for (keycode in pressedKeys) {
|
|
||||||
when (keycode) {
|
|
||||||
Input.Keys.W, Input.Keys.UP -> mapHolder.scrollY -= amountToMove
|
|
||||||
Input.Keys.S, Input.Keys.DOWN -> mapHolder.scrollY += amountToMove
|
|
||||||
Input.Keys.A, Input.Keys.LEFT -> mapHolder.scrollX -= amountToMove
|
|
||||||
Input.Keys.D, Input.Keys.RIGHT -> mapHolder.scrollX += amountToMove
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
mapHolder.updateVisualScroll()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun keyUp(event: InputEvent?, keycode: Int): Boolean {
|
fun whileKeyPressedLoop() {
|
||||||
if (keycode !in ALLOWED_KEYS) return false
|
for (keycode in pressedKeys) {
|
||||||
|
when (keycode) {
|
||||||
pressedKeys.remove(keycode)
|
Input.Keys.W, Input.Keys.UP -> mapHolder.scrollY -= amountToMove
|
||||||
if (infiniteAction != null && pressedKeys.isEmpty()) {
|
Input.Keys.S, Input.Keys.DOWN -> mapHolder.scrollY += amountToMove
|
||||||
// stop the loop otherwise it keeps going even after removal
|
Input.Keys.A, Input.Keys.LEFT -> mapHolder.scrollX -= amountToMove
|
||||||
infiniteAction?.finish()
|
Input.Keys.D, Input.Keys.RIGHT -> mapHolder.scrollX += amountToMove
|
||||||
// remove and nil the action
|
}
|
||||||
mapHolder.removeAction(infiniteAction)
|
}
|
||||||
infiniteAction = null
|
mapHolder.updateVisualScroll()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun keyUp(event: InputEvent?, keycode: Int): Boolean {
|
||||||
|
if (keycode !in ALLOWED_KEYS) return false
|
||||||
|
|
||||||
|
pressedKeys.remove(keycode)
|
||||||
|
if (infiniteAction != null && pressedKeys.isEmpty()) {
|
||||||
|
// stop the loop otherwise it keeps going even after removal
|
||||||
|
infiniteAction?.finish()
|
||||||
|
// remove and nil the action
|
||||||
|
mapHolder.removeAction(infiniteAction)
|
||||||
|
infiniteAction = null
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadLatestMultiplayerState(){
|
private fun loadLatestMultiplayerState() {
|
||||||
|
|
||||||
// Since we're on a background thread, all the UI calls in this func need to run from the
|
// Since we're on a background thread, all the UI calls in this func need to run from the
|
||||||
// main thread which has a GL context
|
// main thread which has a GL context
|
||||||
@ -243,14 +242,13 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
val latestGame = OnlineMultiplayer().tryDownloadGame(gameInfo.gameId)
|
val latestGame = OnlineMultiplayer().tryDownloadGame(gameInfo.gameId)
|
||||||
|
|
||||||
// if we find it still isn't player's turn...nothing changed
|
// if we find it still isn't player's turn...nothing changed
|
||||||
if(gameInfo.isUpToDate && gameInfo.currentPlayer==latestGame.currentPlayer) {
|
if (gameInfo.isUpToDate && gameInfo.currentPlayer == latestGame.currentPlayer) {
|
||||||
Gdx.app.postRunnable { loadingGamePopup.close() }
|
Gdx.app.postRunnable { loadingGamePopup.close() }
|
||||||
return
|
return
|
||||||
}
|
} else { //else we found it is the player's turn again, turn off polling and load turn
|
||||||
else{ //else we found it is the player's turn again, turn off polling and load turn
|
|
||||||
stopMultiPlayerRefresher()
|
stopMultiPlayerRefresher()
|
||||||
|
|
||||||
latestGame.isUpToDate=true
|
latestGame.isUpToDate = true
|
||||||
Gdx.app.postRunnable { game.loadGame(latestGame) }
|
Gdx.app.postRunnable { game.loadGame(latestGame) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,50 +326,50 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
}
|
}
|
||||||
updateNextTurnButton(hasOpenPopups()) // This must be before the notifications update, since its position is based on it
|
updateNextTurnButton(hasOpenPopups()) // This must be before the notifications update, since its position is based on it
|
||||||
notificationsScroll.update(viewingCiv.notifications)
|
notificationsScroll.update(viewingCiv.notifications)
|
||||||
notificationsScroll.setPosition(stage.width - notificationsScroll.width*0.5f - 10f,
|
notificationsScroll.setPosition(stage.width - notificationsScroll.width * 0.5f - 10f,
|
||||||
nextTurnButton.y - notificationsScroll.height*0.5f - 5f)
|
nextTurnButton.y - notificationsScroll.height * 0.5f - 5f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCurrentTutorialTask(): String {
|
private fun getCurrentTutorialTask(): String {
|
||||||
val completedTasks = game.settings.tutorialTasksCompleted
|
val completedTasks = game.settings.tutorialTasksCompleted
|
||||||
if(!completedTasks.contains("Move unit"))
|
if (!completedTasks.contains("Move unit"))
|
||||||
return "Move a unit!\nClick on a unit > Click on a destination > Click the arrow popup"
|
return "Move a unit!\nClick on a unit > Click on a destination > Click the arrow popup"
|
||||||
if(!completedTasks.contains("Found city"))
|
if (!completedTasks.contains("Found city"))
|
||||||
return "Found a city!\nSelect the Settler (flag unit) > Click on 'Found city' (bottom-left corner)"
|
return "Found a city!\nSelect the Settler (flag unit) > Click on 'Found city' (bottom-left corner)"
|
||||||
if(!completedTasks.contains("Enter city screen"))
|
if (!completedTasks.contains("Enter city screen"))
|
||||||
return "Enter the city screen!\nClick the city button twice"
|
return "Enter the city screen!\nClick the city button twice"
|
||||||
if(!completedTasks.contains("Pick technology"))
|
if (!completedTasks.contains("Pick technology"))
|
||||||
return "Pick a technology to research!\nClick on the tech button (greenish, top left) > " +
|
return "Pick a technology to research!\nClick on the tech button (greenish, top left) > " +
|
||||||
"\n select technology > click 'Research' (bottom right)"
|
"\n select technology > click 'Research' (bottom right)"
|
||||||
if(!completedTasks.contains("Pick construction"))
|
if (!completedTasks.contains("Pick construction"))
|
||||||
return "Pick a construction!\nEnter city screen > Click on a unit or building (bottom left side) >" +
|
return "Pick a construction!\nEnter city screen > Click on a unit or building (bottom left side) >" +
|
||||||
" \n click 'add to queue'"
|
" \n click 'add to queue'"
|
||||||
if(!completedTasks.contains("Pass a turn"))
|
if (!completedTasks.contains("Pass a turn"))
|
||||||
return "Pass a turn!\nCycle through units with 'Next unit' > Click 'Next turn'"
|
return "Pass a turn!\nCycle through units with 'Next unit' > Click 'Next turn'"
|
||||||
if(!completedTasks.contains("Reassign worked tiles"))
|
if (!completedTasks.contains("Reassign worked tiles"))
|
||||||
return "Reassign worked tiles!\nEnter city screen > click the assigned (green) tile to unassign > " +
|
return "Reassign worked tiles!\nEnter city screen > click the assigned (green) tile to unassign > " +
|
||||||
"\n click an unassigned tile to assign population"
|
"\n click an unassigned tile to assign population"
|
||||||
if(!completedTasks.contains("Meet another civilization"))
|
if (!completedTasks.contains("Meet another civilization"))
|
||||||
return "Meet another civilization!\nExplore the map until you encounter another civilization!"
|
return "Meet another civilization!\nExplore the map until you encounter another civilization!"
|
||||||
if(!completedTasks.contains("Open the options table"))
|
if (!completedTasks.contains("Open the options table"))
|
||||||
return "Open the options table!\nClick the menu button (top left) > click 'Options'"
|
return "Open the options table!\nClick the menu button (top left) > click 'Options'"
|
||||||
if(!completedTasks.contains("Construct an improvement"))
|
if (!completedTasks.contains("Construct an improvement"))
|
||||||
return "Construct an improvement!\nConstruct a Worker unit > Move to a Plains or Grassland tile > " +
|
return "Construct an improvement!\nConstruct a Worker unit > Move to a Plains or Grassland tile > " +
|
||||||
"\n Click 'Create improvement' (above the unit table, bottom left)" +
|
"\n Click 'Create improvement' (above the unit table, bottom left)" +
|
||||||
"\n > Choose the farm > \n Leave the worker there until it's finished"
|
"\n > Choose the farm > \n Leave the worker there until it's finished"
|
||||||
if(!completedTasks.contains("Create a trade route")
|
if (!completedTasks.contains("Create a trade route")
|
||||||
&& viewingCiv.citiesConnectedToCapitalToMediums.any { it.key.civInfo==viewingCiv })
|
&& viewingCiv.citiesConnectedToCapitalToMediums.any { it.key.civInfo == viewingCiv })
|
||||||
game.settings.addCompletedTutorialTask("Create a trade route")
|
game.settings.addCompletedTutorialTask("Create a trade route")
|
||||||
if(viewingCiv.cities.size>1 && !completedTasks.contains("Create a trade route"))
|
if (viewingCiv.cities.size > 1 && !completedTasks.contains("Create a trade route"))
|
||||||
return "Create a trade route!\nConstruct roads between your capital and another city" +
|
return "Create a trade route!\nConstruct roads between your capital and another city" +
|
||||||
"\nOr, automate your worker and let him get to that eventually"
|
"\nOr, automate your worker and let him get to that eventually"
|
||||||
if(viewingCiv.isAtWar() && !completedTasks.contains("Conquer a city"))
|
if (viewingCiv.isAtWar() && !completedTasks.contains("Conquer a city"))
|
||||||
return "Conquer a city!\nBring an enemy city down to low health > " +
|
return "Conquer a city!\nBring an enemy city down to low health > " +
|
||||||
"\nEnter the city with a melee unit"
|
"\nEnter the city with a melee unit"
|
||||||
if(viewingCiv.getCivUnits().any { it.type.isAirUnit() } && !completedTasks.contains("Move an air unit"))
|
if (viewingCiv.getCivUnits().any { it.type.isAirUnit() } && !completedTasks.contains("Move an air unit"))
|
||||||
return "Move an air unit!\nSelect an air unit > select another city within range > " +
|
return "Move an air unit!\nSelect an air unit > select another city within range > " +
|
||||||
"\nMove the unit to the other city"
|
"\nMove the unit to the other city"
|
||||||
if(!completedTasks.contains("See your stats breakdown"))
|
if (!completedTasks.contains("See your stats breakdown"))
|
||||||
return "See your stats breakdown!\nEnter the Overview screen (top right corner) >" +
|
return "See your stats breakdown!\nEnter the Overview screen (top right corner) >" +
|
||||||
"\nClick on 'Stats'"
|
"\nClick on 'Stats'"
|
||||||
|
|
||||||
@ -398,9 +396,9 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
// ... all tiles around those in range of an average melee unit
|
// ... all tiles around those in range of an average melee unit
|
||||||
// -> and now we look for a unit that could do the conquering because it's ours
|
// -> and now we look for a unit that could do the conquering because it's ours
|
||||||
// no matter whether civilian, air or ranged, tell user he needs melee
|
// no matter whether civilian, air or ranged, tell user he needs melee
|
||||||
.any { it.getUnits().any { unit -> unit.civInfo == viewingCiv} }
|
.any { it.getUnits().any { unit -> unit.civInfo == viewingCiv } }
|
||||||
}
|
}
|
||||||
displayTutorial(Tutorial.AfterConquering) { viewingCiv.cities.any{it.hasJustBeenConquered} }
|
displayTutorial(Tutorial.AfterConquering) { viewingCiv.cities.any { it.hasJustBeenConquered } }
|
||||||
|
|
||||||
displayTutorial(Tutorial.InjuredUnits) { gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.health < 100 } }
|
displayTutorial(Tutorial.InjuredUnits) { gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.health < 100 } }
|
||||||
|
|
||||||
@ -409,8 +407,8 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
|
|
||||||
private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
|
private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
|
||||||
diplomacyButtonHolder.clear()
|
diplomacyButtonHolder.clear()
|
||||||
if(!civInfo.isDefeated() && !civInfo.isSpectator() && civInfo.getKnownCivs()
|
if (!civInfo.isDefeated() && !civInfo.isSpectator() && civInfo.getKnownCivs()
|
||||||
.filterNot { it==viewingCiv || it.isBarbarian() }
|
.filterNot { it == viewingCiv || it.isBarbarian() }
|
||||||
.any()) {
|
.any()) {
|
||||||
displayTutorial(Tutorial.OtherCivEncountered)
|
displayTutorial(Tutorial.OtherCivEncountered)
|
||||||
val btn = "Diplomacy".toTextButton()
|
val btn = "Diplomacy".toTextButton()
|
||||||
@ -439,7 +437,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
val buttonPic = Table()
|
val buttonPic = Table()
|
||||||
buttonPic.background = ImageGetter.getRoundedEdgeTableBackground(colorFromRGB(7, 46, 43))
|
buttonPic.background = ImageGetter.getRoundedEdgeTableBackground(colorFromRGB(7, 46, 43))
|
||||||
buttonPic.defaults().pad(20f)
|
buttonPic.defaults().pad(20f)
|
||||||
val text = if(viewingCiv.tech.canResearchTech()) "{Pick a tech}!" else "Technologies"
|
val text = if (viewingCiv.tech.canResearchTech()) "{Pick a tech}!" else "Technologies"
|
||||||
buttonPic.add(text.toLabel(Color.WHITE, 30))
|
buttonPic.add(text.toLabel(Color.WHITE, 30))
|
||||||
techButtonHolder.add(buttonPic)
|
techButtonHolder.add(buttonPic)
|
||||||
}
|
}
|
||||||
@ -474,7 +472,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
nextTurnButton.label.setFontSize(30)
|
nextTurnButton.label.setFontSize(30)
|
||||||
nextTurnButton.labelCell.pad(10f)
|
nextTurnButton.labelCell.pad(10f)
|
||||||
val nextTurnActionWrapped = { nextTurnAction() }
|
val nextTurnActionWrapped = { nextTurnAction() }
|
||||||
nextTurnButton.onClick (nextTurnActionWrapped)
|
nextTurnButton.onClick(nextTurnActionWrapped)
|
||||||
keyPressDispatcher[' '] = nextTurnActionWrapped
|
keyPressDispatcher[' '] = nextTurnActionWrapped
|
||||||
keyPressDispatcher['n'] = nextTurnActionWrapped
|
keyPressDispatcher['n'] = nextTurnActionWrapped
|
||||||
|
|
||||||
@ -486,13 +484,13 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
shouldUpdate = true
|
shouldUpdate = true
|
||||||
|
|
||||||
|
|
||||||
thread(name="NextTurn") { // on a separate thread so the user can explore their world while we're passing the turn
|
thread(name = "NextTurn") { // on a separate thread so the user can explore their world while we're passing the turn
|
||||||
val gameInfoClone = gameInfo.clone()
|
val gameInfoClone = gameInfo.clone()
|
||||||
gameInfoClone.setTransients()
|
gameInfoClone.setTransients()
|
||||||
try {
|
try {
|
||||||
gameInfoClone.nextTurn()
|
gameInfoClone.nextTurn()
|
||||||
|
|
||||||
if(gameInfo.gameParameters.isOnlineMultiplayer) {
|
if (gameInfo.gameParameters.isOnlineMultiplayer) {
|
||||||
try {
|
try {
|
||||||
OnlineMultiplayer().tryUploadGame(gameInfoClone)
|
OnlineMultiplayer().tryUploadGame(gameInfoClone)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
@ -520,7 +518,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
// do this on main thread - it's the only one that has a GL context to create images from
|
// do this on main thread - it's the only one that has a GL context to create images from
|
||||||
Gdx.app.postRunnable {
|
Gdx.app.postRunnable {
|
||||||
|
|
||||||
fun createNewWorldScreen(){
|
fun createNewWorldScreen() {
|
||||||
val newWorldScreen = WorldScreen(gameInfoClone.getPlayerToViewAs())
|
val newWorldScreen = WorldScreen(gameInfoClone.getPlayerToViewAs())
|
||||||
newWorldScreen.mapHolder.scrollX = mapHolder.scrollX
|
newWorldScreen.mapHolder.scrollX = mapHolder.scrollX
|
||||||
newWorldScreen.mapHolder.scrollY = mapHolder.scrollY
|
newWorldScreen.mapHolder.scrollY = mapHolder.scrollY
|
||||||
@ -542,7 +540,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
createNewWorldScreen()
|
createNewWorldScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shouldAutoSave) {
|
if (shouldAutoSave) {
|
||||||
val newWorldScreen = game.worldScreen
|
val newWorldScreen = game.worldScreen
|
||||||
newWorldScreen.waitingForAutosave = true
|
newWorldScreen.waitingForAutosave = true
|
||||||
newWorldScreen.shouldUpdate = true
|
newWorldScreen.shouldUpdate = true
|
||||||
@ -556,10 +554,10 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NextTurnAction(val text:String, val color:Color, val action:()->Unit)
|
private class NextTurnAction(val text: String, val color: Color, val action: () -> Unit)
|
||||||
|
|
||||||
private fun updateNextTurnButton(isSomethingOpen: Boolean) {
|
private fun updateNextTurnButton(isSomethingOpen: Boolean) {
|
||||||
val action:NextTurnAction = getNextTurnAction()
|
val action: NextTurnAction = getNextTurnAction()
|
||||||
nextTurnAction = action.action
|
nextTurnAction = action.action
|
||||||
|
|
||||||
nextTurnButton.setText(action.text.tr())
|
nextTurnButton.setText(action.text.tr())
|
||||||
@ -568,6 +566,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
nextTurnButton.isEnabled = !isSomethingOpen && isPlayersTurn && !waitingForAutosave
|
nextTurnButton.isEnabled = !isSomethingOpen && isPlayersTurn && !waitingForAutosave
|
||||||
nextTurnButton.setPosition(stage.width - nextTurnButton.width - 10f, topBar.y - nextTurnButton.height - 10f)
|
nextTurnButton.setPosition(stage.width - nextTurnButton.width - 10f, topBar.y - nextTurnButton.height - 10f)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enableNextTurnButtonAfterOptions() {
|
fun enableNextTurnButtonAfterOptions() {
|
||||||
nextTurnButton.isEnabled = isPlayersTurn && !waitingForAutosave
|
nextTurnButton.isEnabled = isPlayersTurn && !waitingForAutosave
|
||||||
}
|
}
|
||||||
@ -598,7 +597,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
game.setScreen(TechPickerScreen(viewingCiv.tech.freeTechs != 0, viewingCiv))
|
game.setScreen(TechPickerScreen(viewingCiv.tech.freeTechs != 0, viewingCiv))
|
||||||
}
|
}
|
||||||
|
|
||||||
viewingCiv.policies.shouldOpenPolicyPicker || (viewingCiv.policies.freePolicies > 0 && viewingCiv.policies.canAdoptPolicy()) ->
|
viewingCiv.policies.shouldOpenPolicyPicker || (viewingCiv.policies.freePolicies > 0 && viewingCiv.policies.canAdoptPolicy()) ->
|
||||||
NextTurnAction("Pick a policy", Color.VIOLET) {
|
NextTurnAction("Pick a policy", Color.VIOLET) {
|
||||||
game.setScreen(PolicyPickerScreen(this))
|
game.setScreen(PolicyPickerScreen(this))
|
||||||
viewingCiv.policies.shouldOpenPolicyPicker = false
|
viewingCiv.policies.shouldOpenPolicyPicker = false
|
||||||
@ -634,10 +633,10 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
super.render(delta)
|
super.render(delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showTutorialsOnNextTurn(){
|
private fun showTutorialsOnNextTurn() {
|
||||||
if (!game.settings.showTutorials) return
|
if (!game.settings.showTutorials) return
|
||||||
displayTutorial(Tutorial.SlowStart)
|
displayTutorial(Tutorial.SlowStart)
|
||||||
displayTutorial(Tutorial.CityExpansion){ viewingCiv.cities.any { it.expansion.tilesClaimed()>0 } }
|
displayTutorial(Tutorial.CityExpansion) { viewingCiv.cities.any { it.expansion.tilesClaimed() > 0 } }
|
||||||
displayTutorial(Tutorial.BarbarianEncountered) { viewingCiv.viewableTiles.any { it.getUnits().any { unit -> unit.civInfo.isBarbarian() } } }
|
displayTutorial(Tutorial.BarbarianEncountered) { viewingCiv.viewableTiles.any { it.getUnits().any { unit -> unit.civInfo.isBarbarian() } } }
|
||||||
displayTutorial(Tutorial.RoadsAndRailroads) { viewingCiv.cities.size > 2 }
|
displayTutorial(Tutorial.RoadsAndRailroads) { viewingCiv.cities.size > 2 }
|
||||||
displayTutorial(Tutorial.Happiness) { viewingCiv.getHappiness() < 5 }
|
displayTutorial(Tutorial.Happiness) { viewingCiv.getHappiness() < 5 }
|
||||||
@ -646,11 +645,11 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
displayTutorial(Tutorial.IdleUnits) { gameInfo.turns >= 50 && game.settings.checkForDueUnits }
|
displayTutorial(Tutorial.IdleUnits) { gameInfo.turns >= 50 && game.settings.checkForDueUnits }
|
||||||
displayTutorial(Tutorial.ContactMe) { gameInfo.turns >= 100 }
|
displayTutorial(Tutorial.ContactMe) { gameInfo.turns >= 100 }
|
||||||
val resources = viewingCiv.detailedCivResources.asSequence().filter { it.origin == "All" } // Avoid full list copy
|
val resources = viewingCiv.detailedCivResources.asSequence().filter { it.origin == "All" } // Avoid full list copy
|
||||||
displayTutorial(Tutorial.LuxuryResource) { resources.any { it.resource.resourceType==ResourceType.Luxury } }
|
displayTutorial(Tutorial.LuxuryResource) { resources.any { it.resource.resourceType == ResourceType.Luxury } }
|
||||||
displayTutorial(Tutorial.StrategicResource) { resources.any { it.resource.resourceType==ResourceType.Strategic} }
|
displayTutorial(Tutorial.StrategicResource) { resources.any { it.resource.resourceType == ResourceType.Strategic } }
|
||||||
displayTutorial(Tutorial.EnemyCity) {
|
displayTutorial(Tutorial.EnemyCity) {
|
||||||
viewingCiv.getKnownCivs().asSequence().filter { viewingCiv.isAtWarWith(it) }
|
viewingCiv.getKnownCivs().asSequence().filter { viewingCiv.isAtWarWith(it) }
|
||||||
.flatMap { it.cities.asSequence() }.any { viewingCiv.exploredTiles.contains(it.location) }
|
.flatMap { it.cities.asSequence() }.any { viewingCiv.exploredTiles.contains(it.location) }
|
||||||
}
|
}
|
||||||
displayTutorial(Tutorial.ApolloProgram) { viewingCiv.hasUnique("Enables construction of Spaceship parts") }
|
displayTutorial(Tutorial.ApolloProgram) { viewingCiv.hasUnique("Enables construction of Spaceship parts") }
|
||||||
displayTutorial(Tutorial.SiegeUnits) { viewingCiv.getCivUnits().any { it.type == UnitType.Siege } }
|
displayTutorial(Tutorial.SiegeUnits) { viewingCiv.getCivUnits().any { it.type == UnitType.Siege } }
|
||||||
@ -693,17 +692,14 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
|||||||
promptWindow.addGoodSizedLabel("Do you want to exit the game?".tr())
|
promptWindow.addGoodSizedLabel("Do you want to exit the game?".tr())
|
||||||
promptWindow.row()
|
promptWindow.row()
|
||||||
promptWindow.addButton("Yes") { Gdx.app.exit() }
|
promptWindow.addButton("Yes") { Gdx.app.exit() }
|
||||||
promptWindow.addButton("No") {
|
promptWindow.addButton("No") { promptWindow.close() }
|
||||||
promptWindow.close()
|
|
||||||
}
|
|
||||||
// show the dialog
|
// show the dialog
|
||||||
promptWindow.open (true) // true = always on top
|
promptWindow.open(true) // true = always on top
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// this object must not be created multiple times
|
// this object must not be created multiple times
|
||||||
private var multiPlayerRefresher : Timer? = null
|
private var multiPlayerRefresher: Timer? = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user