mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-07 14:02:48 +07:00
Added experimental scenarios!
This commit is contained in:
parent
8e2b443427
commit
c3d592393e
@ -826,6 +826,7 @@ Default Font =
|
||||
|
||||
Max zoom out =
|
||||
Enable Easter Eggs =
|
||||
Enable Scenarios (experimental) =
|
||||
Enlarge selected notifications =
|
||||
|
||||
Generate translation files =
|
||||
@ -1835,6 +1836,7 @@ Date ↓ =
|
||||
Stars ↓ =
|
||||
Status ↓ =
|
||||
|
||||
Scenarios =
|
||||
|
||||
# Uniques that are relevant to more than one type of game object
|
||||
|
||||
|
@ -89,7 +89,7 @@ class Civilization : IsPartOfGameInfoSerialization {
|
||||
|
||||
@Transient
|
||||
val units = UnitManager(this)
|
||||
|
||||
|
||||
@Transient
|
||||
var threatManager = ThreatManager(this)
|
||||
|
||||
@ -321,7 +321,9 @@ class Civilization : IsPartOfGameInfoSerialization {
|
||||
* city-states to contain the barbarians. Therefore, [getKnownCivs] will **not** list the barbarians
|
||||
* for major civs, but **will** do so for city-states after some gameplay.
|
||||
*/
|
||||
fun getKnownCivs() = diplomacy.values.asSequence().map { it.otherCiv() }.filter { !it.isDefeated() }
|
||||
fun getKnownCivs() = diplomacy.values.asSequence().map { it.otherCiv() }
|
||||
.filter { !it.isDefeated() && !it.isSpectator() }
|
||||
|
||||
fun knows(otherCivName: String) = diplomacy.containsKey(otherCivName)
|
||||
fun knows(otherCiv: Civilization) = knows(otherCiv.civName)
|
||||
|
||||
|
@ -15,9 +15,12 @@ import com.unciv.logic.GameInfoPreview
|
||||
import com.unciv.logic.GameInfoSerializationVersion
|
||||
import com.unciv.logic.HasGameInfoSerializationVersion
|
||||
import com.unciv.logic.UncivShowableException
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.civilization.managers.TurnManager
|
||||
import com.unciv.models.metadata.GameSettings
|
||||
import com.unciv.models.metadata.doMigrations
|
||||
import com.unciv.models.metadata.isMigrationNecessary
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.ui.screens.savescreens.Gzip
|
||||
import com.unciv.utils.Concurrency
|
||||
import com.unciv.utils.Log
|
||||
@ -309,6 +312,31 @@ class UncivFiles(
|
||||
getGeneralSettingsFile().writeString(json().toJson(gameSettings), false, Charsets.UTF_8.name())
|
||||
}
|
||||
|
||||
val scenarioFolder = "scenarios"
|
||||
fun getScenarioFiles() = sequence {
|
||||
|
||||
for (mod in RulesetCache.values) {
|
||||
val modFolder = mod.folderLocation ?: continue
|
||||
val scenarioFolder = modFolder.child(scenarioFolder)
|
||||
if (scenarioFolder.exists())
|
||||
for (file in scenarioFolder.list())
|
||||
yield(Pair(file, mod))
|
||||
}
|
||||
}
|
||||
|
||||
fun loadScenario(gameFile: FileHandle): GameInfo {
|
||||
val game = loadGameFromFile(gameFile)
|
||||
game.civilizations.removeAll { it.isSpectator() }
|
||||
if (game.civilizations.none { it.isHuman() })
|
||||
game.civilizations.first { it.isMajorCiv() }.playerType = PlayerType.Human
|
||||
|
||||
game.currentPlayerCiv = game.civilizations.first { it.playerType == PlayerType.Human }
|
||||
game.currentPlayer = game.currentPlayerCiv.civName
|
||||
TurnManager(game.currentPlayerCiv).startTurn()
|
||||
|
||||
return game
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
var saveZipped = false
|
||||
|
@ -91,7 +91,7 @@ class GameSettings {
|
||||
var androidHideSystemUi = true
|
||||
|
||||
var multiplayer = GameSettingsMultiplayer()
|
||||
|
||||
|
||||
var autoPlay = GameSettingsAutoPlay()
|
||||
|
||||
var enableEspionageOption = false
|
||||
@ -336,21 +336,21 @@ class GameSettings {
|
||||
var autoPlayPolicies: Boolean = true
|
||||
var autoPlayReligion: Boolean = true
|
||||
var autoPlayDiplomacy: Boolean = true
|
||||
|
||||
|
||||
var turnsToAutoPlay: Int = 0
|
||||
var autoPlayTurnInProgress: Boolean = false
|
||||
|
||||
|
||||
fun startAutoPlay() {
|
||||
turnsToAutoPlay = autoPlayMaxTurns
|
||||
}
|
||||
|
||||
|
||||
fun stopAutoPlay() {
|
||||
turnsToAutoPlay = 0
|
||||
autoPlayTurnInProgress = false
|
||||
}
|
||||
|
||||
|
||||
fun isAutoPlaying(): Boolean = turnsToAutoPlay > 0
|
||||
|
||||
|
||||
fun isAutoPlayingAndFullAI():Boolean = isAutoPlaying() && fullAutoPlayAI
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ enum class KeyboardBinding(
|
||||
Multiplayer(Category.MainMenu), // Name disambiguation maybe soon, not yet necessary
|
||||
MapEditor(Category.MainMenu, "Map editor", KeyCharAndCode('E')),
|
||||
ModManager(Category.MainMenu, "Mods", KeyCharAndCode('D')),
|
||||
Scenarios(Category.MainMenu, "Scenarios", KeyCharAndCode('S')),
|
||||
MainMenuOptions(Category.MainMenu, "Options", KeyCharAndCode('O')), // Separate binding from World where it's Ctrl-O default
|
||||
|
||||
// Worldscreen
|
||||
|
@ -17,8 +17,8 @@ import com.unciv.Constants
|
||||
import com.unciv.GUI
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.models.metadata.GameSettings
|
||||
import com.unciv.models.metadata.ModCategories
|
||||
import com.unciv.models.metadata.GameSettings.ScreenSize
|
||||
import com.unciv.models.metadata.ModCategories
|
||||
import com.unciv.models.translations.TranslationFileWriter
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.UncivTooltip.Companion.addTooltip
|
||||
@ -42,11 +42,11 @@ import com.unciv.utils.Concurrency
|
||||
import com.unciv.utils.Display
|
||||
import com.unciv.utils.ScreenOrientation
|
||||
import com.unciv.utils.launchOnGLThread
|
||||
import java.util.UUID
|
||||
import java.util.zip.Deflater
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.UUID
|
||||
import java.util.zip.Deflater
|
||||
|
||||
fun advancedTab(
|
||||
optionsPopup: OptionsPopup,
|
||||
|
@ -167,6 +167,12 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
|
||||
{ game.pushScreen(ModManagementScreen()) }
|
||||
column2.add(modsTable).row()
|
||||
|
||||
if (game.files.getScenarioFiles().any()){
|
||||
val scenarioTable = getMenuButton("Scenarios", "OtherIcons/Mods", KeyboardBinding.Scenarios)
|
||||
{ game.pushScreen(ScenarioScreen()) }
|
||||
column2.add(scenarioTable).row()
|
||||
}
|
||||
|
||||
val optionsTable = getMenuButton("Options", "OtherIcons/Options", KeyboardBinding.MainMenuOptions)
|
||||
{ openOptionsPopup() }
|
||||
optionsTable.onLongPress { openOptionsPopup(withDebug = true) }
|
||||
@ -352,3 +358,5 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
|
||||
// We contain a map...
|
||||
override fun getShortcutDispatcherVetoer() = KeyShortcutDispatcherVeto.createTileGroupMapDispatcherVetoer()
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,44 @@
|
||||
package com.unciv.ui.screens.mainmenuscreen
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.extensions.enable
|
||||
import com.unciv.ui.components.extensions.toTextButton
|
||||
import com.unciv.ui.components.input.onClick
|
||||
import com.unciv.ui.screens.pickerscreens.PickerScreen
|
||||
import com.unciv.utils.Concurrency
|
||||
|
||||
class ScenarioScreen: PickerScreen() {
|
||||
|
||||
private var scenarioToLoad: FileHandle? = null
|
||||
|
||||
init {
|
||||
val scenarioFiles = game.files.getScenarioFiles()
|
||||
rightSideButton.setText("Choose scenario")
|
||||
Concurrency.run {
|
||||
for ((file, mod) in scenarioFiles) {
|
||||
try {
|
||||
val scenarioPreview = game.files.loadGamePreviewFromFile(file)
|
||||
Concurrency.runOnGLThread {
|
||||
topTable.add(file.name().toTextButton().onClick {
|
||||
descriptionLabel.setText("Mod: [${mod.name}]".tr())
|
||||
scenarioToLoad = file
|
||||
rightSideButton.setText(file.name())
|
||||
rightSideButton.enable()
|
||||
})
|
||||
}
|
||||
} catch (ex: Exception) { } // invalid, couldn't even load preview, probably invalid json
|
||||
}
|
||||
}
|
||||
|
||||
rightSideButton.onClick {
|
||||
if (scenarioToLoad != null)
|
||||
Concurrency.run {
|
||||
val scenario = game.files.loadScenario(scenarioToLoad!!)
|
||||
game.loadGame(scenario)
|
||||
}
|
||||
}
|
||||
|
||||
setDefaultCloseAction()
|
||||
}
|
||||
}
|
20
docs/Modders/Scenarios.md
Normal file
20
docs/Modders/Scenarios.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Scenarios
|
||||
|
||||
Scenarios are specific game states, set up so a player has a specific experience.
|
||||
|
||||
These can range from just having cities and units in specific places, to having full-blown custom rulesets to support them.
|
||||
|
||||
When creating a mod, we differentiate the *ruleset* from the *scenario* - the scenario is just a specific game state, or in other words - a saved game.
|
||||
|
||||
|
||||
To create a scenario:
|
||||
- Create a new game with the players you want, AND a spectator
|
||||
- Enter the game as the spectator, and edit the save using the console
|
||||
- Save the game, copy the game save file to a "scenarios" folder in your mod
|
||||
|
||||
## Console
|
||||
|
||||
To open the console, click the "`" button on your keyboard.
|
||||
|
||||
To see available commands, click enter. This works for subcommands as well (e.g. when you entered `tile`)
|
||||
|
Loading…
Reference in New Issue
Block a user