mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-08 14:57:58 +07:00
Lots off background work for future water tiles
Resized xxxhdpi icon
This commit is contained in:
BIN
android/ImagesToNotAddToGame/uncivicon2.png
Normal file
BIN
android/ImagesToNotAddToGame/uncivicon2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 366 KiB |
@ -1,15 +1,29 @@
|
|||||||
[
|
[
|
||||||
// Base terrains
|
// Base terrains
|
||||||
|
{
|
||||||
|
name:"Ocean",
|
||||||
|
type:"Water",
|
||||||
|
food:2,
|
||||||
|
movementCost:1,
|
||||||
|
RGB: [100,100,255]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:"Coast",
|
||||||
|
type:"Water",
|
||||||
|
food:2,
|
||||||
|
movementCost:1,
|
||||||
|
RGB: [150,150,255]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name:"Grassland",
|
name:"Grassland",
|
||||||
type:"BaseTerrain",
|
type:"Land",
|
||||||
food:2,
|
food:2,
|
||||||
movementCost:1,
|
movementCost:1,
|
||||||
RGB: [109,139,53]
|
RGB: [109,139,53]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Plains",
|
name:"Plains",
|
||||||
type:"BaseTerrain",
|
type:"Land",
|
||||||
food:1,
|
food:1,
|
||||||
production:1,
|
production:1,
|
||||||
movementCost:1,
|
movementCost:1,
|
||||||
@ -17,27 +31,28 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Tundra",
|
name:"Tundra",
|
||||||
type:"BaseTerrain",
|
type:"Land",
|
||||||
food:1,
|
food:1,
|
||||||
movementCost:1,
|
movementCost:1,
|
||||||
RGB: [125,122,113]
|
RGB: [125,122,113]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Desert",
|
name:"Desert",
|
||||||
type:"BaseTerrain",
|
type:"Land",
|
||||||
movementCost:1,
|
movementCost:1,
|
||||||
RGB: [ 255, 255, 102]
|
RGB: [ 255, 255, 102]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Lakes",
|
name:"Lakes",
|
||||||
type:"BaseTerrain",
|
type:"Water",
|
||||||
food:1,
|
food:1,
|
||||||
gold:1
|
gold:1,
|
||||||
|
RGB: [ 200, 200, 255],
|
||||||
canHaveOverlay:false
|
canHaveOverlay:false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name:"Hill",
|
name:"Hill",
|
||||||
type:"BaseTerrain",
|
type:"Land",
|
||||||
production:2,
|
production:2,
|
||||||
movementCost:2,
|
movementCost:2,
|
||||||
defenceBonus: 0.25,
|
defenceBonus: 0.25,
|
||||||
|
@ -21,8 +21,8 @@ android {
|
|||||||
applicationId "com.unciv.game"
|
applicationId "com.unciv.game"
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion 26
|
targetSdkVersion 26
|
||||||
versionCode 135
|
versionCode 137
|
||||||
versionName "2.8.3"
|
versionName "2.8.5"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 366 KiB After Width: | Height: | Size: 13 KiB |
@ -281,7 +281,7 @@ class UnitAutomation{
|
|||||||
|
|
||||||
// find best city location within 5 tiles
|
// find best city location within 5 tiles
|
||||||
val tilesNearCities = unit.civInfo.gameInfo.civilizations.flatMap { it.cities }
|
val tilesNearCities = unit.civInfo.gameInfo.civilizations.flatMap { it.cities }
|
||||||
.flatMap { it.getCenterTile().getTilesInDistance(2) }
|
.flatMap { it.getCenterTile().getTilesInDistance(3) }
|
||||||
|
|
||||||
// This is to improve performance - instead of ranking each tile in the area up to 19 times, do it once.
|
// This is to improve performance - instead of ranking each tile in the area up to 19 times, do it once.
|
||||||
val nearbyTileRankings = unit.getTile().getTilesInDistance(7)
|
val nearbyTileRankings = unit.getTile().getTilesInDistance(7)
|
||||||
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Vector2
|
|||||||
import com.unciv.logic.automation.WorkerAutomation
|
import com.unciv.logic.automation.WorkerAutomation
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
import com.unciv.models.gamebasics.GameBasics
|
import com.unciv.models.gamebasics.GameBasics
|
||||||
|
import com.unciv.models.gamebasics.tile.TerrainType
|
||||||
import com.unciv.models.gamebasics.unit.BaseUnit
|
import com.unciv.models.gamebasics.unit.BaseUnit
|
||||||
import com.unciv.models.gamebasics.unit.UnitType
|
import com.unciv.models.gamebasics.unit.UnitType
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
@ -89,6 +90,8 @@ class MapUnit {
|
|||||||
*/
|
*/
|
||||||
fun canMoveTo(tile: TileInfo): Boolean {
|
fun canMoveTo(tile: TileInfo): Boolean {
|
||||||
val tileOwner = tile.getOwner()
|
val tileOwner = tile.getOwner()
|
||||||
|
if(tile.getBaseTerrain().type==TerrainType.Water && baseUnit.unitType.isLandUnit())
|
||||||
|
return false
|
||||||
if(tileOwner!=null && tileOwner.civName!=owner
|
if(tileOwner!=null && tileOwner.civName!=owner
|
||||||
&& (tile.isCityCenter() || !civInfo.canEnterTiles(tileOwner))) return false
|
&& (tile.isCityCenter() || !civInfo.canEnterTiles(tileOwner))) return false
|
||||||
|
|
||||||
|
@ -8,16 +8,46 @@ import com.unciv.models.gamebasics.tile.TerrainType
|
|||||||
import com.unciv.models.gamebasics.tile.TileResource
|
import com.unciv.models.gamebasics.tile.TileResource
|
||||||
import com.unciv.ui.utils.getRandom
|
import com.unciv.ui.utils.getRandom
|
||||||
|
|
||||||
class SeedRandomMapGenerator : RandomMapGenerator() {
|
class AlexanderRandomMapGenerator:RandomMapGenerator(){
|
||||||
|
fun generateMap(distance: Int, landExpansionChange:Float){
|
||||||
override fun generateMap(distance: Int): HashMap<String, TileInfo> {
|
|
||||||
|
|
||||||
val map = HashMap<Vector2, TileInfo?>()
|
val map = HashMap<Vector2, TileInfo?>()
|
||||||
|
|
||||||
for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance))
|
for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance))
|
||||||
map[vector] = null
|
map[vector] = null
|
||||||
|
|
||||||
class Area(val terrain: String) {
|
val sparkList = ArrayList<Vector2>()
|
||||||
|
val grassland = "Grassland"
|
||||||
|
val ocean = "Ocean"
|
||||||
|
for(i in 0..distance*distance/6){
|
||||||
|
val location = map.filter { it.value==null }.map { it.key }.getRandom()
|
||||||
|
map[location] = TileInfo().apply { baseTerrain= grassland}
|
||||||
|
sparkList.add(location)
|
||||||
|
}
|
||||||
|
|
||||||
|
while(sparkList.any()){
|
||||||
|
val currentSpark = sparkList.getRandom()
|
||||||
|
val emptyTilesAroundSpark = HexMath().GetAdjacentVectors(currentSpark)
|
||||||
|
.filter { map.containsKey(it) && map[it]==null }
|
||||||
|
if(map[currentSpark]!!.baseTerrain==grassland){
|
||||||
|
for(tile in emptyTilesAroundSpark){
|
||||||
|
if(Math.random()<landExpansionChange) map[tile]=TileInfo().apply { baseTerrain=grassland }
|
||||||
|
else map[tile]=TileInfo().apply { baseTerrain=ocean }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
for(tile in emptyTilesAroundSpark)
|
||||||
|
map[tile]=TileInfo().apply { baseTerrain=ocean }
|
||||||
|
}
|
||||||
|
sparkList.remove(currentSpark)
|
||||||
|
sparkList.addAll(emptyTilesAroundSpark)
|
||||||
|
}
|
||||||
|
|
||||||
|
// now that we've divided them into land and not-land, stage 2 - seeding areas the way we did with the seed generator!
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Area(var terrain: String) {
|
||||||
val locations = ArrayList<Vector2>()
|
val locations = ArrayList<Vector2>()
|
||||||
fun addTile(position: Vector2) : TileInfo{
|
fun addTile(position: Vector2) : TileInfo{
|
||||||
locations+=position
|
locations+=position
|
||||||
@ -25,51 +55,28 @@ class SeedRandomMapGenerator : RandomMapGenerator() {
|
|||||||
val tile = TileInfo()
|
val tile = TileInfo()
|
||||||
tile.position = position
|
tile.position = position
|
||||||
tile.baseTerrain = terrain
|
tile.baseTerrain = terrain
|
||||||
addRandomOverlay(tile)
|
RandomMapGenerator().addRandomTerrainFeature(tile)
|
||||||
addRandomResourceToTile(tile)
|
RandomMapGenerator().addRandomResourceToTile(tile)
|
||||||
return tile
|
return tile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val areas = ArrayList<Area>()
|
/**
|
||||||
|
* This generator works by creating a number of seeds of different terrain types in random places,
|
||||||
|
* and choosing a random one each time to expand in a random direction, until the map is filled.
|
||||||
|
* With water, this creates canal-like structures.
|
||||||
|
*/
|
||||||
|
class SeedRandomMapGenerator : RandomMapGenerator() {
|
||||||
|
|
||||||
val terrains = GameBasics.Terrains.values.filter { it.type === TerrainType.BaseTerrain && it.name != "Lakes" }
|
fun generateMap(distance: Int, waterPercent:Float): HashMap<String, TileInfo> {
|
||||||
|
|
||||||
|
val map = HashMap<Vector2, TileInfo?>()
|
||||||
|
|
||||||
|
for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance))
|
||||||
|
map[vector] = null
|
||||||
|
|
||||||
|
|
||||||
for (i in 0..(distance*distance/2)){
|
divideIntoAreas(6, waterPercent, map)
|
||||||
val area = Area(terrains.getRandom().name)
|
|
||||||
val location = map.filter { it.value==null }.map { it.key }.getRandom()
|
|
||||||
map[location] = area.addTile(location)
|
|
||||||
areas += area
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun expandAreas(){
|
|
||||||
val expandableAreas = ArrayList<Area>(areas)
|
|
||||||
while (expandableAreas.isNotEmpty()){
|
|
||||||
val areaToExpand = expandableAreas.getRandom()
|
|
||||||
val availableExpansionVectors = areaToExpand.locations.flatMap { HexMath().GetAdjacentVectors(it) }.distinct()
|
|
||||||
.filter { map.containsKey(it) && map[it] == null }
|
|
||||||
if(availableExpansionVectors.isEmpty()) expandableAreas -= areaToExpand
|
|
||||||
else {
|
|
||||||
val expansionVector = availableExpansionVectors.getRandom()
|
|
||||||
map[expansionVector] = areaToExpand.addTile(expansionVector)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expandAreas()
|
|
||||||
|
|
||||||
// After we've assigned all the tiles, there will be some areas that contain only 1 or 2 tiles.
|
|
||||||
// So, we kill those areas, and have the world expand on and cover them too.
|
|
||||||
for(area in areas.toList()){
|
|
||||||
if(area.locations.size<3){
|
|
||||||
areas -= area
|
|
||||||
for(location in area.locations) map[location] = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expandAreas()
|
|
||||||
|
|
||||||
val mapToReturn = HashMap<String,TileInfo>()
|
val mapToReturn = HashMap<String,TileInfo>()
|
||||||
for (entry in map){
|
for (entry in map){
|
||||||
@ -78,8 +85,83 @@ class SeedRandomMapGenerator : RandomMapGenerator() {
|
|||||||
|
|
||||||
return mapToReturn
|
return mapToReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun divideIntoAreas(averageTilesPerArea: Int, waterPercent: Float, map: HashMap<Vector2, TileInfo?>) {
|
||||||
|
val areas = ArrayList<Area>()
|
||||||
|
|
||||||
|
val terrains = GameBasics.Terrains.values.filter { it.type === TerrainType.Land && it.name != "Lakes" }
|
||||||
|
|
||||||
|
for (i in 0..(map.count { it.value==null } / averageTilesPerArea)) {
|
||||||
|
val terrain = if (Math.random() > waterPercent) terrains.getRandom().name
|
||||||
|
else "Ocean"
|
||||||
|
val area = Area(terrain)
|
||||||
|
val location = map.filter { it.value == null }.map { it.key }.getRandom()
|
||||||
|
map[location] = area.addTile(location)
|
||||||
|
areas += area
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun expandAreas() {
|
||||||
|
val expandableAreas = ArrayList<Area>(areas)
|
||||||
|
while (expandableAreas.isNotEmpty()) {
|
||||||
|
val areaToExpand = expandableAreas.getRandom()
|
||||||
|
val availableExpansionVectors = areaToExpand.locations
|
||||||
|
.flatMap { HexMath().GetAdjacentVectors(it) }.distinct()
|
||||||
|
.filter { map.containsKey(it) && map[it] == null }
|
||||||
|
if (availableExpansionVectors.isEmpty()) expandableAreas -= areaToExpand
|
||||||
|
else {
|
||||||
|
val expansionVector = availableExpansionVectors.getRandom()
|
||||||
|
map[expansionVector] = areaToExpand.addTile(expansionVector)
|
||||||
|
|
||||||
|
val neighbors = HexMath().GetAdjacentVectors(expansionVector)
|
||||||
|
val areasToJoin = areas.filter {
|
||||||
|
it.terrain == areaToExpand.terrain
|
||||||
|
&& it != areaToExpand
|
||||||
|
&& it.locations.any { location -> location in neighbors }
|
||||||
|
}
|
||||||
|
for (area in areasToJoin) {
|
||||||
|
areaToExpand.locations += area.locations
|
||||||
|
areas.remove(area)
|
||||||
|
expandableAreas.remove(area)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expandAreas()
|
||||||
|
|
||||||
|
// After we've assigned all the tiles, there will be some areas that contain only 1 or 2 tiles.
|
||||||
|
// So, we kill those areas, and have the world expand on and cover them too
|
||||||
|
for (area in areas.toList()) {
|
||||||
|
if (area.locations.size < 3) {
|
||||||
|
areas -= area
|
||||||
|
for (location in area.locations) map[location] = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expandAreas()
|
||||||
|
|
||||||
|
// Once our map has all its tiles, we'll want to change the water tiles to Coasts, Oceans and Lakes
|
||||||
|
|
||||||
|
for (area in areas.filter { it.terrain == "Ocean" && it.locations.size <= 10 }) {
|
||||||
|
// areas with 10 or less tiles are lakes.
|
||||||
|
for (location in area.locations)
|
||||||
|
map[location]!!.baseTerrain = "Lakes"
|
||||||
|
}
|
||||||
|
for (tile in map.values.filter { it != null && it.baseTerrain == "Ocean" }) {
|
||||||
|
if (HexMath().GetAdjacentVectors(tile!!.position)
|
||||||
|
.any { map.containsKey(it) && map[it]!!.getBaseTerrain().type == TerrainType.Land })
|
||||||
|
tile.baseTerrain = "Coast"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This contains the basic randomizing tasks (add random terrain feature/resource)
|
||||||
|
* and a basic map generator where every single tile is individually randomized.
|
||||||
|
* DDoeesn't look very good TBH.
|
||||||
|
*/
|
||||||
open class RandomMapGenerator {
|
open class RandomMapGenerator {
|
||||||
|
|
||||||
private fun addRandomTile(position: Vector2): TileInfo {
|
private fun addRandomTile(position: Vector2): TileInfo {
|
||||||
@ -87,16 +169,16 @@ open class RandomMapGenerator {
|
|||||||
tileInfo.position = position
|
tileInfo.position = position
|
||||||
val terrains = GameBasics.Terrains.values
|
val terrains = GameBasics.Terrains.values
|
||||||
|
|
||||||
val baseTerrain = terrains.filter { it.type === TerrainType.BaseTerrain && it.name != "Lakes" }.getRandom()
|
val baseTerrain = terrains.filter { it.type === TerrainType.Land && it.name != "Lakes" }.getRandom()
|
||||||
tileInfo.baseTerrain = baseTerrain.name
|
tileInfo.baseTerrain = baseTerrain.name
|
||||||
|
|
||||||
addRandomOverlay(tileInfo)
|
addRandomTerrainFeature(tileInfo)
|
||||||
addRandomResourceToTile(tileInfo)
|
addRandomResourceToTile(tileInfo)
|
||||||
|
|
||||||
return tileInfo
|
return tileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun addRandomOverlay(tileInfo: TileInfo) {
|
fun addRandomTerrainFeature(tileInfo: TileInfo) {
|
||||||
if (tileInfo.getBaseTerrain().canHaveOverlay && Math.random() > 0.7f) {
|
if (tileInfo.getBaseTerrain().canHaveOverlay && Math.random() > 0.7f) {
|
||||||
val secondaryTerrains = GameBasics.Terrains.values
|
val secondaryTerrains = GameBasics.Terrains.values
|
||||||
.filter { it.type === TerrainType.TerrainFeature && it.occursOn!!.contains(tileInfo.baseTerrain) }
|
.filter { it.type === TerrainType.TerrainFeature && it.occursOn!!.contains(tileInfo.baseTerrain) }
|
||||||
@ -127,7 +209,6 @@ open class RandomMapGenerator {
|
|||||||
else return filtered.getRandom()
|
else return filtered.getRandom()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun generateMap(distance: Int): HashMap<String, TileInfo> {
|
open fun generateMap(distance: Int): HashMap<String, TileInfo> {
|
||||||
val map = HashMap<String, TileInfo>()
|
val map = HashMap<String, TileInfo>()
|
||||||
for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance))
|
for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance))
|
||||||
|
@ -31,7 +31,7 @@ class TileMap {
|
|||||||
|
|
||||||
|
|
||||||
constructor(distance: Int) {
|
constructor(distance: Int) {
|
||||||
tileList.addAll(SeedRandomMapGenerator().generateMap(distance).values)
|
tileList.addAll(SeedRandomMapGenerator().generateMap(distance,0f).values)
|
||||||
setTransients()
|
setTransients()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.unciv.logic.map
|
package com.unciv.logic.map
|
||||||
|
|
||||||
import com.badlogic.gdx.math.Vector2
|
import com.badlogic.gdx.math.Vector2
|
||||||
|
import com.unciv.models.gamebasics.tile.TerrainType
|
||||||
|
|
||||||
class UnitMovementAlgorithms(val unit:MapUnit) {
|
class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||||
val tileMap = unit.getTile().tileMap
|
val tileMap = unit.getTile().tileMap
|
||||||
@ -37,7 +38,8 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
|||||||
var totalDistanceToTile:Float
|
var totalDistanceToTile:Float
|
||||||
val neighborOwner = neighbor.getOwner()
|
val neighborOwner = neighbor.getOwner()
|
||||||
val isOwnedByEnemy = neighborOwner!=null && neighborOwner!=unit.civInfo
|
val isOwnedByEnemy = neighborOwner!=null && neighborOwner!=unit.civInfo
|
||||||
if ((isOwnedByEnemy && neighbor.isCityCenter())// Enemy city,
|
if ( (unit.baseUnit.unitType.isLandUnit() && neighbor.getBaseTerrain().type== TerrainType.Water)
|
||||||
|
|| (isOwnedByEnemy && neighbor.isCityCenter())// Enemy city,
|
||||||
|| (neighbor.getUnits().isNotEmpty() && neighbor.getUnits().first().civInfo!=unit.civInfo) // Enemy unit
|
|| (neighbor.getUnits().isNotEmpty() && neighbor.getUnits().first().civInfo!=unit.civInfo) // Enemy unit
|
||||||
|| (isOwnedByEnemy && !unit.civInfo.canEnterTiles(neighborOwner!!)) // enemyTile
|
|| (isOwnedByEnemy && !unit.civInfo.canEnterTiles(neighborOwner!!)) // enemyTile
|
||||||
)
|
)
|
||||||
|
@ -51,6 +51,7 @@ class Terrain : NamedStats(), ICivilopedia {
|
|||||||
var RGB: List<Int>? = null
|
var RGB: List<Int>? = null
|
||||||
var movementCost = 1
|
var movementCost = 1
|
||||||
var defenceBonus:Float = 0f
|
var defenceBonus:Float = 0f
|
||||||
|
var impassible = false
|
||||||
|
|
||||||
fun getColor(): Color = colorFromRGB(RGB!![0], RGB!![1], RGB!![2])
|
fun getColor(): Color = colorFromRGB(RGB!![0], RGB!![1], RGB!![2])
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package com.unciv.models.gamebasics.tile
|
package com.unciv.models.gamebasics.tile
|
||||||
|
|
||||||
enum class TerrainType {
|
enum class TerrainType {
|
||||||
BaseTerrain,
|
Land,
|
||||||
|
Water,
|
||||||
TerrainFeature
|
TerrainFeature
|
||||||
}
|
}
|
||||||
|
@ -15,4 +15,8 @@ enum class UnitType{
|
|||||||
fun isRanged(): Boolean {
|
fun isRanged(): Boolean {
|
||||||
return this in listOf(Ranged, Siege)
|
return this in listOf(Ranged, Siege)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isLandUnit(): Boolean {
|
||||||
|
return this in listOf(Civilian, Melee, Mounted, Scout, Ranged, Siege)
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user