mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-26 21:35:14 -04:00
MainMenu Background Map scaled to Screen and minor MapGen fixes (#7000)
* MapGenerator fixes * MainMenu Background Map scaled to Screen * MainMenu Background Map scaled to Screen - groupSize as public const
This commit is contained in:
parent
56f11ccdca
commit
cdeabd044d
@ -10,7 +10,6 @@ import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.GameStarter
|
||||
import com.unciv.logic.map.MapParameters
|
||||
import com.unciv.logic.map.MapShape
|
||||
import com.unciv.logic.map.MapSize
|
||||
import com.unciv.logic.map.MapSizeNew
|
||||
import com.unciv.logic.map.MapType
|
||||
import com.unciv.logic.map.mapgenerator.MapGenerator
|
||||
@ -23,6 +22,7 @@ import com.unciv.ui.civilopedia.CivilopediaScreen
|
||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||
import com.unciv.ui.images.ImageGetter
|
||||
import com.unciv.ui.map.TileGroupMap
|
||||
import com.unciv.ui.newgamescreen.NewGameScreen
|
||||
import com.unciv.ui.pickerscreens.ModManagementScreen
|
||||
import com.unciv.ui.popup.*
|
||||
@ -31,6 +31,8 @@ import com.unciv.ui.saves.QuickSave
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip
|
||||
import com.unciv.ui.worldscreen.mainmenu.WorldScreenMenuPopup
|
||||
import kotlin.math.min
|
||||
|
||||
|
||||
class MainMenuScreen: BaseScreen() {
|
||||
private val backgroundTable = Table().apply { background= ImageGetter.getBackground(Color.WHITE) }
|
||||
@ -76,16 +78,29 @@ class MainMenuScreen: BaseScreen() {
|
||||
ImageGetter.ruleset = RulesetCache.getVanillaRuleset()
|
||||
|
||||
launchCrashHandling("ShowMapBackground") {
|
||||
val newMap = MapGenerator(RulesetCache.getVanillaRuleset())
|
||||
var scale = 1f
|
||||
var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance
|
||||
var mapHeight = stage.height / TileGroupMap.groupSize
|
||||
if (mapWidth * mapHeight > 3000f) { // 3000 as max estimated number of tiles is arbitrary (we had typically 721 before)
|
||||
scale = mapWidth * mapHeight / 3000f
|
||||
mapWidth /= scale
|
||||
mapHeight /= scale
|
||||
scale = min(scale, 20f)
|
||||
}
|
||||
|
||||
val mapRuleset = RulesetCache.getVanillaRuleset()
|
||||
val newMap = MapGenerator(mapRuleset)
|
||||
.generateMap(MapParameters().apply {
|
||||
shape = MapShape.rectangular
|
||||
mapSize = MapSizeNew(MapSize.Small)
|
||||
mapSize = MapSizeNew(mapWidth.toInt() + 1, mapHeight.toInt() + 1)
|
||||
type = MapType.default
|
||||
waterThreshold = -0.055f // Gives the same level as when waterThreshold was unused in MapType.default
|
||||
})
|
||||
|
||||
postCrashHandlingRunnable { // for GL context
|
||||
ImageGetter.setNewRuleset(RulesetCache.getVanillaRuleset())
|
||||
ImageGetter.setNewRuleset(mapRuleset)
|
||||
val mapHolder = EditorMapHolder(this@MainMenuScreen, newMap) {}
|
||||
mapHolder.setScale(scale)
|
||||
backgroundTable.addAction(Actions.sequence(
|
||||
Actions.fadeOut(0f),
|
||||
Actions.run {
|
||||
|
@ -25,6 +25,7 @@ import kotlin.math.max
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sign
|
||||
import kotlin.math.ulp
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
@ -45,13 +46,26 @@ class MapGenerator(val ruleset: Ruleset) {
|
||||
/** builds a [TerrainOccursRange] for [terrain] from a [unique] (type [UniqueType.TileGenerationConditions]) */
|
||||
constructor(terrain: Terrain, unique: Unique)
|
||||
: this(terrain,
|
||||
unique.params[0].toFloat(), unique.params[1].toFloat(),
|
||||
unique.params[2].toFloat(), unique.params[3].toFloat())
|
||||
/** checks if both [temperature] and [humidity] satisfy their ranges (>From, <=To) */
|
||||
unique.params[0].toFloatMakeInclusive(-1f), unique.params[1].toFloat(),
|
||||
unique.params[2].toFloatMakeInclusive(0f), unique.params[3].toFloat())
|
||||
|
||||
/** Checks if both [temperature] and [humidity] satisfy their ranges (>From, <=To)
|
||||
* Note the lowest allowed limit has been made inclusive (temp -1 nudged down by 1 [Float.ulp], humidity at 0)
|
||||
*/
|
||||
|
||||
// Yes this does implicit conversions Float/Double
|
||||
fun matches(temperature: Double, humidity: Double) =
|
||||
tempFrom < temperature && temperature <= tempTo &&
|
||||
humidFrom < humidity && humidity <= humidTo
|
||||
|
||||
companion object {
|
||||
/** A [toFloat] that also nudges the value slightly down if it matches [limit] to make the resulting range inclusive on the lower end */
|
||||
private fun String.toFloatMakeInclusive(limit: Float): Float {
|
||||
val result = toFloat()
|
||||
if (result != limit) return result
|
||||
return result - result.ulp
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun Terrain.getGenerationConditions() =
|
||||
getMatchingUniques(UniqueType.TileGenerationConditions)
|
||||
@ -463,11 +477,15 @@ class MapGenerator(val ruleset: Ruleset) {
|
||||
|
||||
// List is OK here as it's only sequentially scanned
|
||||
val limitsMap: List<TerrainOccursRange> =
|
||||
ruleset.terrains.values.flatMap {
|
||||
it.getGenerationConditions()
|
||||
}
|
||||
ruleset.terrains.values.filter { it.type == TerrainType.Land }
|
||||
.flatMap { it.getGenerationConditions() }
|
||||
val noTerrainUniques = limitsMap.isEmpty()
|
||||
val elevationTerrains = arrayOf(Constants.mountain, Constants.hill)
|
||||
val elevationTerrains = ruleset.terrains.values.asSequence()
|
||||
.filter {
|
||||
it.hasUnique(UniqueType.OccursInChains)
|
||||
}.mapTo(mutableSetOf()) { it.name }
|
||||
if (elevationTerrains.isEmpty())
|
||||
elevationTerrains.add(Constants.mountain)
|
||||
|
||||
for (tile in tileMap.values.asSequence()) {
|
||||
if (tile.isWater || tile.baseTerrain in elevationTerrains)
|
||||
@ -526,6 +544,7 @@ class MapGenerator(val ruleset: Ruleset) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [MapParameters.rareFeaturesRichness] is the probability of spawning a rare feature
|
||||
*/
|
||||
@ -600,16 +619,21 @@ class MapGenerationRandomness {
|
||||
/**
|
||||
* Generates a perlin noise channel combining multiple octaves
|
||||
*
|
||||
* [nOctaves] is the number of octaves
|
||||
* [persistence] is the scaling factor of octave amplitudes
|
||||
* [lacunarity] is the scaling factor of octave frequencies
|
||||
* [scale] is the distance the noise is observed from
|
||||
* @param tile Source for x / x coordinates.
|
||||
* @param seed Misnomer: actually the z value the Perlin cloud is 'cut' on.
|
||||
* @param nOctaves is the number of octaves.
|
||||
* @param persistence is the scaling factor of octave amplitudes.
|
||||
* @param lacunarity is the scaling factor of octave frequencies.
|
||||
* @param scale is the distance the noise is observed from.
|
||||
*/
|
||||
fun getPerlinNoise(tile: TileInfo, seed: Double,
|
||||
nOctaves: Int = 6,
|
||||
persistence: Double = 0.5,
|
||||
lacunarity: Double = 2.0,
|
||||
scale: Double = 10.0): Double {
|
||||
fun getPerlinNoise(
|
||||
tile: TileInfo,
|
||||
seed: Double,
|
||||
nOctaves: Int = 6,
|
||||
persistence: Double = 0.5,
|
||||
lacunarity: Double = 2.0,
|
||||
scale: Double = 10.0
|
||||
): Double {
|
||||
val worldCoords = HexMath.hex2WorldCoords(tile.position)
|
||||
return Perlin.noise3d(worldCoords.x.toDouble(), worldCoords.y.toDouble(), seed, nOctaves, persistence, lacunarity, scale)
|
||||
}
|
||||
|
@ -25,6 +25,21 @@ class TileGroupMap<T: TileGroup>(
|
||||
worldWrap: Boolean = false,
|
||||
tileGroupsToUnwrap: Set<T>? = null
|
||||
): Group() {
|
||||
companion object {
|
||||
/** Vertical size of a hex in world coordinates, or the distance between the centers of any two opposing edges
|
||||
* (the hex is oriented so it has corners to the left and right of the center and its upper and lower bounds are horizontal edges) */
|
||||
const val groupSize = 50f
|
||||
/** Length of the diagonal of a hex, or distance between two opposing corners */
|
||||
const val groupSizeDiagonal = groupSize * 1.1547005f // groupSize * sqrt(4/3)
|
||||
/** Horizontal displacement per hex, meaning the increase in overall map size (in world coordinates) when adding a column.
|
||||
* On the hex, this can be visualized as the horizontal distance between the leftmost corner and the
|
||||
* line connecting the two corners at 2 and 4 o'clock. */
|
||||
const val groupHorizontalAdvance = groupSizeDiagonal * 3 / 4
|
||||
//TODO magic numbers that **seem** like they might depend on these values can be found in
|
||||
// TileGroupMap.getPositionalVector, TileGroup.updateArrows, TileGroup.updateRoadImages
|
||||
// and other places. I can't understand them so I'm leaving cleanup of hardcoding to someone else.
|
||||
}
|
||||
|
||||
/** If the [act] method should be performed. If this is false, every child within this [TileGroupMap] will not get their [act] method called
|
||||
* and thus not perform any [com.badlogic.gdx.scenes.scene2d.Action]s.
|
||||
* Most children here already do not do anything in their [act] methods. However, even iterating through all of them */
|
||||
@ -34,7 +49,6 @@ class TileGroupMap<T: TileGroup>(
|
||||
private var topY = -Float.MAX_VALUE
|
||||
private var bottomX = Float.MAX_VALUE
|
||||
private var bottomY = Float.MAX_VALUE
|
||||
private val groupSize = 50
|
||||
private val mirrorTileGroups = HashMap<TileInfo, Pair<T, T>>()
|
||||
|
||||
init {
|
||||
@ -54,8 +68,8 @@ class TileGroupMap<T: TileGroup>(
|
||||
HexMath.hex2WorldCoords(tileGroup.tileInfo.position)
|
||||
}
|
||||
|
||||
tileGroup.setPosition(positionalVector.x * 0.8f * groupSize.toFloat(),
|
||||
positionalVector.y * 0.8f * groupSize.toFloat())
|
||||
tileGroup.setPosition(positionalVector.x * 0.8f * groupSize,
|
||||
positionalVector.y * 0.8f * groupSize)
|
||||
|
||||
topX =
|
||||
if (worldWrap)
|
||||
@ -82,12 +96,12 @@ class TileGroupMap<T: TileGroup>(
|
||||
for (mirrorTiles in mirrorTileGroups.values){
|
||||
val positionalVector = HexMath.hex2WorldCoords(mirrorTiles.first.tileInfo.position)
|
||||
|
||||
mirrorTiles.first.setPosition(positionalVector.x * 0.8f * groupSize.toFloat(),
|
||||
positionalVector.y * 0.8f * groupSize.toFloat())
|
||||
mirrorTiles.first.setPosition(positionalVector.x * 0.8f * groupSize,
|
||||
positionalVector.y * 0.8f * groupSize)
|
||||
mirrorTiles.first.moveBy(-bottomX - bottomX * 2, -bottomY )
|
||||
|
||||
mirrorTiles.second.setPosition(positionalVector.x * 0.8f * groupSize.toFloat(),
|
||||
positionalVector.y * 0.8f * groupSize.toFloat())
|
||||
mirrorTiles.second.setPosition(positionalVector.x * 0.8f * groupSize,
|
||||
positionalVector.y * 0.8f * groupSize)
|
||||
mirrorTiles.second.moveBy(-bottomX + bottomX * 2, -bottomY)
|
||||
}
|
||||
}
|
||||
@ -157,21 +171,22 @@ class TileGroupMap<T: TileGroup>(
|
||||
* Returns the positional coordinates of the TileGroupMap center.
|
||||
*/
|
||||
fun getPositionalVector(stageCoords: Vector2): Vector2 {
|
||||
val trueGroupSize = 0.8f * groupSize.toFloat()
|
||||
val trueGroupSize = 0.8f * groupSize
|
||||
return Vector2(bottomX, bottomY)
|
||||
.add(stageCoords)
|
||||
.sub(groupSize.toFloat() / 2f, groupSize.toFloat() / 2f)
|
||||
.sub(groupSize / 2f, groupSize / 2f)
|
||||
.scl(1f / trueGroupSize)
|
||||
}
|
||||
|
||||
fun getMirrorTiles(): HashMap<TileInfo, Pair<T, T>> = mirrorTileGroups
|
||||
|
||||
override fun act(delta: Float) {
|
||||
if(shouldAct) {
|
||||
super.act(delta)
|
||||
}
|
||||
}
|
||||
|
||||
// For debugging purposes
|
||||
override fun draw(batch: Batch?, parentAlpha: Float) { super.draw(batch, parentAlpha) }
|
||||
@Suppress("RedundantOverride")
|
||||
override fun act(delta: Float) {
|
||||
if(shouldAct) {
|
||||
super.act(delta)
|
||||
}
|
||||
}
|
||||
override fun draw(batch: Batch?, parentAlpha: Float) { super.draw(batch, parentAlpha) }
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user