Skip to content

Commit

Permalink
Implement a waiting command (#6884) (#6896)
Browse files Browse the repository at this point in the history
* Implement a waiting command (#6884)

* Resolve misc. issues with commit 27a03bc

* Resolve misc. issues with commit 93d9fe9

* Resolve misc. issues with commit 2ca7ed1

Co-authored-by: Paul Pogonyshev <[email protected]>
  • Loading branch information
SomeTroglodyte and doublep authored May 25, 2022
1 parent 0661bbc commit 16874f5
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 25 deletions.
54 changes: 44 additions & 10 deletions core/src/com/unciv/logic/civilization/CivilizationInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ class CivilizationInfo {
@Transient
private var units = listOf<MapUnit>()

/**
* Index in the unit list above of the unit that is potentially due and is next up for button "Next unit".
*/
@Transient
private var nextPotentiallyDueAt = 0

@Transient
var viewableTiles = setOf<TileInfo>()

Expand Down Expand Up @@ -448,10 +454,19 @@ class CivilizationInfo {
fun getCivUnits(): Sequence<MapUnit> = units.asSequence()
fun getCivGreatPeople(): Sequence<MapUnit> = getCivUnits().filter { mapUnit -> mapUnit.isGreatPerson() }

// Similar to getCivUnits(), but the returned list is rotated so that the
// 'nextPotentiallyDueAt' unit is first here.
private fun getCivUnitsStartingAtNextDue(): Sequence<MapUnit> = sequenceOf(units.subList(nextPotentiallyDueAt, units.size) + units.subList(0, nextPotentiallyDueAt)).flatten()

fun addUnit(mapUnit: MapUnit, updateCivInfo: Boolean = true) {
val newList = ArrayList(units)
// Since we create a new list anyway (otherwise some concurrent modification
// exception will happen), also rearrange existing units so that
// 'nextPotentiallyDueAt' becomes 0. This way new units are always last to be due
// (can be changed as wanted, just have a predictable place).
var newList = getCivUnitsStartingAtNextDue().toMutableList()
newList.add(mapUnit)
units = newList
nextPotentiallyDueAt = 0

if (updateCivInfo) {
// Not relevant when updating TileInfo transients, since some info of the civ itself isn't yet available,
Expand All @@ -462,27 +477,46 @@ class CivilizationInfo {
}

fun removeUnit(mapUnit: MapUnit) {
val newList = ArrayList(units)
// See comment in addUnit().
var newList = getCivUnitsStartingAtNextDue().toMutableList()
newList.remove(mapUnit)
units = newList
nextPotentiallyDueAt = 0

updateStatsForNextTurn() // unit upkeep
updateDetailedCivResources()
}

fun getIdleUnits() = getCivUnits().filter { it.isIdle() }

private fun getDueUnits() = getCivUnits().filter { it.due && it.isIdle() }
fun getDueUnits(): Sequence<MapUnit> = getCivUnitsStartingAtNextDue().filter { it.due && it.isIdle() }

fun shouldGoToDueUnit() = UncivGame.Current.settings.checkForDueUnits && getDueUnits().any()

fun getNextDueUnit(): MapUnit? {
val dueUnits = getDueUnits()
if (dueUnits.any()) {
val unit = dueUnits.first()
unit.due = false
return unit
// Return the next due unit, but preferably not 'unitToSkip': this is returned only if it is the only remaining due unit.
fun cycleThroughDueUnits(unitToSkip: MapUnit? = null): MapUnit? {
if (units.none()) return null

var returnAt = nextPotentiallyDueAt
var fallbackAt = -1

do {
if (units[returnAt].due && units[returnAt].isIdle()) {
if (units[returnAt] != unitToSkip) {
nextPotentiallyDueAt = (returnAt + 1) % units.size
return units[returnAt]
}
else fallbackAt = returnAt
}

returnAt = (returnAt + 1) % units.size
} while (returnAt != nextPotentiallyDueAt)

if (fallbackAt >= 0) {
nextPotentiallyDueAt = (fallbackAt + 1) % units.size
return units[fallbackAt]
}
return null
else return null
}
//endregion

Expand Down
2 changes: 2 additions & 0 deletions core/src/com/unciv/models/UnitAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ enum class UnitActionType(
{ ImageGetter.getImage("OtherIcons/DisbandUnit") }, KeyCharAndCode.DEL),
GiftUnit("Gift unit",
{ ImageGetter.getImage("OtherIcons/Present") }, UncivSound.Silent),
Wait("Wait",
null, 'z', UncivSound.Silent),
ShowAdditionalActions("Show more",
{ imageGetShowMore() }, KeyCharAndCode(Input.Keys.PAGE_DOWN)),
HideAdditionalActions("Back",
Expand Down
30 changes: 17 additions & 13 deletions core/src/com/unciv/ui/worldscreen/WorldScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
else
mapHolder.setCenterPosition(tileToCenterOn, immediately = true, selectUnit = true)


tutorialController.allTutorialsShowedCallback = { shouldUpdate = true }

onBackButtonClicked { backButtonAndESCHandler() }
Expand Down Expand Up @@ -723,6 +722,22 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
}
}

fun switchToNextUnit() {
// Try to select something new if we already have the next pending unit selected.
val nextDueUnit = viewingCiv.cycleThroughDueUnits(bottomUnitTable.selectedUnit)
if (nextDueUnit != null) {
mapHolder.setCenterPosition(
nextDueUnit.currentTile.position,
immediately = false,
selectUnit = false
)
bottomUnitTable.selectUnit(nextDueUnit)
shouldUpdate = true
// Unless 'wait' action is chosen, the unit will not be considered due anymore.
nextDueUnit.due = false
}
}

private fun updateNextTurnButton(isSomethingOpen: Boolean) {
nextTurnButton.update(isSomethingOpen, isPlayersTurn, waitingForAutosave, getNextTurnAction())
nextTurnButton.setPosition(stage.width - nextTurnButton.width - 10f, topBar.y - nextTurnButton.height - 10f)
Expand All @@ -737,18 +752,7 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
NextTurnAction("Waiting for other players...",Color.GRAY) {}

viewingCiv.shouldGoToDueUnit() ->
NextTurnAction("Next unit", Color.LIGHT_GRAY) {
val nextDueUnit = viewingCiv.getNextDueUnit()
if (nextDueUnit != null) {
mapHolder.setCenterPosition(
nextDueUnit.currentTile.position,
immediately = false,
selectUnit = false
)
bottomUnitTable.selectUnit(nextDueUnit)
shouldUpdate = true
}
}
NextTurnAction("Next unit", Color.LIGHT_GRAY) { switchToNextUnit() }

viewingCiv.cities.any { it.cityConstructions.currentConstructionFromQueue == "" } ->
NextTurnAction("Pick construction", Color.CORAL) {
Expand Down
16 changes: 14 additions & 2 deletions core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ object UnitActions {
addTriggerUniqueActions(unit, actionList)
addAddInCapitalAction(unit, actionList, tile)

addWaitAction(unit, actionList, worldScreen);

addToggleActionsAction(unit, actionList, unitTable)

Expand Down Expand Up @@ -821,6 +822,18 @@ object UnitActions {
}
}

private fun addWaitAction(unit: MapUnit, actionList: ArrayList<UnitAction>, worldScreen: WorldScreen) {
if (!unit.isIdle()) return
if (worldScreen.viewingCiv.getDueUnits().filter { it != unit }.none()) return
actionList += UnitAction(
type = UnitActionType.Wait,
action = {
unit.due = true
worldScreen.switchToNextUnit()
}
)
}

private fun addToggleActionsAction(unit: MapUnit, actionList: ArrayList<UnitAction>, unitTable: UnitTable) {
actionList += UnitAction(
type = if (unit.showAdditionalActions) UnitActionType.HideAdditionalActions
Expand All @@ -831,5 +844,4 @@ object UnitActions {
}
)
}

}
}

0 comments on commit 16874f5

Please sign in to comment.