mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 22:06:05 -04:00
Merge pull request #334 from ninjatao/add_battleship
Add Battleship. Enabled Electronics for battleship.
This commit is contained in:
commit
ac241d2744
@ -62,6 +62,8 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
|
|||||||
* [Helmet](https://thenounproject.com/term/helmet/25216/) By Daniel Turner for Great War Infantry
|
* [Helmet](https://thenounproject.com/term/helmet/25216/) By Daniel Turner for Great War Infantry
|
||||||
* [Tank](https://thenounproject.com/term/tank/1287510/) By corpus delicti for Landship
|
* [Tank](https://thenounproject.com/term/tank/1287510/) By corpus delicti for Landship
|
||||||
* [Warship](https://thenounproject.com/term/warship/1597474/) By zidney for Destroyer
|
* [Warship](https://thenounproject.com/term/warship/1597474/) By zidney for Destroyer
|
||||||
|
* [Battleship](https://thenounproject.com/search/?q=battleship&i=1986807) By Vitaliy Gorbachev, KZ for Battleship
|
||||||
|
* [Submarine](https://thenounproject.com/search/?q=submarine&i=589519) By Hea Poh Lin, MY
|
||||||
|
|
||||||
### Great People
|
### Great People
|
||||||
|
|
||||||
@ -345,6 +347,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
|
|||||||
* [Plastic](https://thenounproject.com/term/plastic/478826/) By Yu luck
|
* [Plastic](https://thenounproject.com/term/plastic/478826/) By Yu luck
|
||||||
* [Microphone](https://thenounproject.com/term/microphone/470266/) By Viktor Vorobyev for Mass Media
|
* [Microphone](https://thenounproject.com/term/microphone/470266/) By Viktor Vorobyev for Mass Media
|
||||||
* [Flight](https://thenounproject.com/term/flight/1014306/) By Genius Icons
|
* [Flight](https://thenounproject.com/term/flight/1014306/) By Genius Icons
|
||||||
|
* [Refridgerator](https://thenounproject.com/search/?q=refridgerator&i=1188873) By b farias, CL
|
||||||
|
|
||||||
### Information
|
### Information
|
||||||
* [Pill](https://thenounproject.com/term/pill/780458/) By Alex Arseneau for Pharmaceuticals
|
* [Pill](https://thenounproject.com/term/pill/780458/) By Alex Arseneau for Pharmaceuticals
|
||||||
@ -357,6 +360,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc
|
|||||||
### Future
|
### Future
|
||||||
* [Nanoparticles](https://thenounproject.com/term/nanoparticles/822286/) By Gyan Lakhwani for Nanotechnology
|
* [Nanoparticles](https://thenounproject.com/term/nanoparticles/822286/) By Gyan Lakhwani for Nanotechnology
|
||||||
* [Satellite](https://thenounproject.com/term/satellite/1466641/) By Ben Davis for Satellites
|
* [Satellite](https://thenounproject.com/term/satellite/1466641/) By Ben Davis for Satellites
|
||||||
|
* [Electronics](https://thenounproject.com/search/?q=Electronics&i=1565843) By Cuby Design
|
||||||
* [Atom](https://thenounproject.com/term/atom/1586852/) By Kelsey Armstrong for Particle Physics
|
* [Atom](https://thenounproject.com/term/atom/1586852/) By Kelsey Armstrong for Particle Physics
|
||||||
* [Information Technology](https://thenounproject.com/term/information-technology/1927668/) By Vectors Markeet for Future Tech
|
* [Information Technology](https://thenounproject.com/term/information-technology/1927668/) By Vectors Markeet for Future Tech
|
||||||
|
|
||||||
|
BIN
android/Images/TechIcons/Electronics.png
Normal file
BIN
android/Images/TechIcons/Electronics.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
android/Images/TechIcons/Refrigeration.png
Normal file
BIN
android/Images/TechIcons/Refrigeration.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
BIN
android/Images/UnitIcons/Battleship.png
Normal file
BIN
android/Images/UnitIcons/Battleship.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
android/Images/UnitIcons/Submarine.png
Normal file
BIN
android/Images/UnitIcons/Submarine.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 968 B |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 818 KiB After Width: | Height: | Size: 825 KiB |
@ -356,13 +356,12 @@
|
|||||||
techCost: 4505,
|
techCost: 4505,
|
||||||
buildingCost:500,
|
buildingCost:500,
|
||||||
wonderCost:1250,
|
wonderCost:1250,
|
||||||
techs:[/*
|
techs:[
|
||||||
{
|
{
|
||||||
name:"Refrigeration",
|
name:"Refrigeration",
|
||||||
row:4,
|
row:3,
|
||||||
prerequisites:["Electricity"],
|
prerequisites:["Biology", "Electricity"], //to do: offshore platform should need this
|
||||||
baseDescription:"Does nothing since we have no sea tiles - In theory, allows construction of offshore platforms and submarines"
|
},
|
||||||
},*/
|
|
||||||
{
|
{
|
||||||
name:"Replacable Parts",
|
name:"Replacable Parts",
|
||||||
row:4,
|
row:4,
|
||||||
@ -391,13 +390,12 @@
|
|||||||
name:"Plastics",
|
name:"Plastics",
|
||||||
row:3,
|
row:3,
|
||||||
prerequisites:["Biology","Replacable Parts"]
|
prerequisites:["Biology","Replacable Parts"]
|
||||||
},/*
|
},
|
||||||
{
|
{
|
||||||
name:"Electronics",
|
name:"Electronics",
|
||||||
row:5,
|
row:5,
|
||||||
prerequisites:["Radio"],
|
prerequisites:["Replacable Parts", "Flight"],
|
||||||
baseDescription:"Contributes only war-relatied things - on hold until AI is introduced - todo"
|
},
|
||||||
},*/
|
|
||||||
{
|
{
|
||||||
name:"Mass Media",
|
name:"Mass Media",
|
||||||
row:6,
|
row:6,
|
||||||
|
@ -368,6 +368,8 @@
|
|||||||
cost: 185,
|
cost: 185,
|
||||||
requiredResource:"Iron",
|
requiredResource:"Iron",
|
||||||
requiredTech:"Navigation",
|
requiredTech:"Navigation",
|
||||||
|
obsoleteTech:"Electronics",
|
||||||
|
upgradesTo:"Battleship",
|
||||||
hurryCostModifier:20
|
hurryCostModifier:20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -465,7 +467,31 @@
|
|||||||
strength:55,
|
strength:55,
|
||||||
cost: 375,
|
cost: 375,
|
||||||
requiredTech:"Combustion",
|
requiredTech:"Combustion",
|
||||||
uniques:[], // todo: add interception and bonus vs submarines once we have air and submarine units
|
uniques:["Can attack submarines"], // todo: add interception and bonus vs submarines once we have air and submarine units
|
||||||
|
hurryCostModifier:20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Battleship",
|
||||||
|
unitType: "WaterRanged",
|
||||||
|
movement: 5,
|
||||||
|
strength: 55,
|
||||||
|
rangedStrength: 55,
|
||||||
|
range: 3,
|
||||||
|
cost: 375,
|
||||||
|
requiredResource:"Oil",
|
||||||
|
requiredTech:"Electronics",
|
||||||
|
uniques:["Indirect Fire", "Bonus vs City 30%"],
|
||||||
|
hurryCostModifier:20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Submarine",
|
||||||
|
unitType: "WaterRanged",
|
||||||
|
movement: 5,
|
||||||
|
strength: 35,
|
||||||
|
rangedStrength: 60,
|
||||||
|
cost: 325,
|
||||||
|
requiredTech:"Refrigeration",
|
||||||
|
uniques:["Bonus as Attacker 75%", "Invisible to others", "Can Only Attack Water", "Can attack submarines"], //to do: 3 uniques
|
||||||
hurryCostModifier:20
|
hurryCostModifier:20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -118,6 +118,12 @@ class UnitAutomation{
|
|||||||
if(tileCombatant==null) return false
|
if(tileCombatant==null) return false
|
||||||
if(tileCombatant.getCivilization()==unit.civInfo ) return false
|
if(tileCombatant.getCivilization()==unit.civInfo ) return false
|
||||||
if(!unit.civInfo.isAtWarWith(tileCombatant.getCivilization())) return false
|
if(!unit.civInfo.isAtWarWith(tileCombatant.getCivilization())) return false
|
||||||
|
|
||||||
|
//only submarine and destroyer can attack submarine
|
||||||
|
if (tileCombatant.isInvisible()
|
||||||
|
&& (!unit.hasUnique("Can attack submarines") || !unit.civInfo.viewableInvisibleUnitsTiles.map { it.position }.contains(tile.position))){
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,12 @@ class BattleDamage{
|
|||||||
else modifiers[text] = BDM.modificationAmount
|
else modifiers[text] = BDM.modificationAmount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ability in attacker.unit.getUniques()) {
|
||||||
|
val regexResult = Regex("""Bonus as Attacker (\d*)%""").matchEntire(ability) //to do: extend to defender, and penalyy
|
||||||
|
if (regexResult == null) continue
|
||||||
|
modifiers["Attacker Bonus"] = regexResult.groups[1]!!.value.toFloat() / 100
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attacker.isMelee()) {
|
if (attacker.isMelee()) {
|
||||||
|
@ -12,6 +12,7 @@ class CityCombatant(val city: CityInfo) : ICombatant {
|
|||||||
override fun getTile(): TileInfo = city.getCenterTile()
|
override fun getTile(): TileInfo = city.getCenterTile()
|
||||||
override fun getName(): String = city.name
|
override fun getName(): String = city.name
|
||||||
override fun isDefeated(): Boolean = city.health==1
|
override fun isDefeated(): Boolean = city.health==1
|
||||||
|
override fun isInvisible(): Boolean = false
|
||||||
|
|
||||||
override fun takeDamage(damage: Int) {
|
override fun takeDamage(damage: Int) {
|
||||||
city.health -= damage
|
city.health -= damage
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.unciv.logic.battle
|
package com.unciv.logic.battle
|
||||||
|
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
import com.unciv.logic.civilization.CivilizationInfo
|
||||||
|
import com.unciv.logic.map.MapUnit
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.models.gamebasics.unit.UnitType
|
import com.unciv.models.gamebasics.unit.UnitType
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ interface ICombatant{
|
|||||||
fun isDefeated():Boolean
|
fun isDefeated():Boolean
|
||||||
fun getCivilization(): CivilizationInfo
|
fun getCivilization(): CivilizationInfo
|
||||||
fun getTile(): TileInfo
|
fun getTile(): TileInfo
|
||||||
|
fun isInvisible(): Boolean
|
||||||
|
|
||||||
fun isMelee(): Boolean {
|
fun isMelee(): Boolean {
|
||||||
return this.getUnitType().isMelee()
|
return this.getUnitType().isMelee()
|
||||||
|
@ -11,6 +11,7 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
|||||||
override fun getTile(): TileInfo = unit.getTile()
|
override fun getTile(): TileInfo = unit.getTile()
|
||||||
override fun getName(): String = unit.name
|
override fun getName(): String = unit.name
|
||||||
override fun isDefeated(): Boolean = unit.health <= 0
|
override fun isDefeated(): Boolean = unit.health <= 0
|
||||||
|
override fun isInvisible(): Boolean = unit.isInvisible()
|
||||||
|
|
||||||
override fun takeDamage(damage: Int) {
|
override fun takeDamage(damage: Int) {
|
||||||
unit.health -= damage
|
unit.health -= damage
|
||||||
|
@ -33,6 +33,7 @@ class CivilizationInfo {
|
|||||||
*/
|
*/
|
||||||
@Transient private var units=ArrayList<MapUnit>()
|
@Transient private var units=ArrayList<MapUnit>()
|
||||||
@Transient var viewableTiles = HashSet<TileInfo>()
|
@Transient var viewableTiles = HashSet<TileInfo>()
|
||||||
|
@Transient var viewableInvisibleUnitsTiles = HashSet<TileInfo>()
|
||||||
|
|
||||||
var gold = 0
|
var gold = 0
|
||||||
var happiness = 15
|
var happiness = 15
|
||||||
@ -228,6 +229,9 @@ class CivilizationInfo {
|
|||||||
newViewableTiles.addAll(getCivUnits().flatMap { it.getViewableTiles()})
|
newViewableTiles.addAll(getCivUnits().flatMap { it.getViewableTiles()})
|
||||||
viewableTiles = newViewableTiles // to avoid concurrent modification problems
|
viewableTiles = newViewableTiles // to avoid concurrent modification problems
|
||||||
|
|
||||||
|
val newViewableInvisibleTiles = HashSet<TileInfo>()
|
||||||
|
newViewableInvisibleTiles.addAll(getCivUnits().filter {it.hasUnique("Can attack submarines")}.flatMap {it.getViewableTiles()})
|
||||||
|
viewableInvisibleUnitsTiles = newViewableInvisibleTiles
|
||||||
// updating the viewable tiles also affects the explored tiles, obvs
|
// updating the viewable tiles also affects the explored tiles, obvs
|
||||||
|
|
||||||
val newExploredTiles = HashSet<Vector2>(exploredTiles)
|
val newExploredTiles = HashSet<Vector2>(exploredTiles)
|
||||||
|
@ -178,6 +178,12 @@ class MapUnit {
|
|||||||
return currentTile.baseTerrain=="Ocean"||currentTile.baseTerrain=="Coast"
|
return currentTile.baseTerrain=="Ocean"||currentTile.baseTerrain=="Coast"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isInvisible(): Boolean {
|
||||||
|
if(hasUnique("Invisible to others"))
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
fun getEmbarkedMovement(): Int {
|
fun getEmbarkedMovement(): Int {
|
||||||
var movement=2
|
var movement=2
|
||||||
movement += civInfo.tech.getUniques().count { it == "Increases embarked movement +1" }
|
movement += civInfo.tech.getUniques().count { it == "Increases embarked movement +1" }
|
||||||
|
@ -281,5 +281,14 @@ open class TileInfo {
|
|||||||
turnsToImprovement = improvement.getTurnsToBuild(civInfo)
|
turnsToImprovement = improvement.getTurnsToBuild(civInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun hasEnemySubmarine(): Boolean {
|
||||||
|
val unitsInTile = getUnits()
|
||||||
|
if (unitsInTile.isEmpty()) return false
|
||||||
|
if (!unitsInTile.first().civInfo.isPlayerCivilization() &&
|
||||||
|
unitsInTile.firstOrNull {it.isInvisible() == true} != null) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
@ -23,8 +23,10 @@ class CityTileGroup(private val city: CityInfo, tileInfo: TileInfo) : TileGroup(
|
|||||||
fun update() {
|
fun update() {
|
||||||
val canSeeTile = UnCivGame.Current.viewEntireMapForDebug
|
val canSeeTile = UnCivGame.Current.viewEntireMapForDebug
|
||||||
|| city.civInfo.viewableTiles.contains(tileInfo)
|
|| city.civInfo.viewableTiles.contains(tileInfo)
|
||||||
|
val showSubmarine = UnCivGame.Current.viewEntireMapForDebug
|
||||||
super.update(canSeeTile,true)
|
|| city.civInfo.viewableInvisibleUnitsTiles.contains(tileInfo)
|
||||||
|
|| (!tileInfo.hasEnemySubmarine())
|
||||||
|
super.update(canSeeTile,true, showSubmarine)
|
||||||
|
|
||||||
updatePopulationImage()
|
updatePopulationImage()
|
||||||
if (improvementImage != null) improvementImage!!.setColor(1f, 1f, 1f, 0.5f)
|
if (improvementImage != null) improvementImage!!.setColor(1f, 1f, 1f, 0.5f)
|
||||||
|
@ -133,7 +133,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun update(isViewable: Boolean, showResourcesAndImprovements:Boolean) {
|
open fun update(isViewable: Boolean, showResourcesAndImprovements:Boolean, showSubmarine: Boolean) {
|
||||||
hideCircle()
|
hideCircle()
|
||||||
if (!UnCivGame.Current.viewEntireMapForDebug
|
if (!UnCivGame.Current.viewEntireMapForDebug
|
||||||
&& !tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position)) {
|
&& !tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position)) {
|
||||||
@ -150,7 +150,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
|||||||
|
|
||||||
|
|
||||||
civilianUnitImage = newUnitImage(tileInfo.civilianUnit, civilianUnitImage, isViewable, -20f)
|
civilianUnitImage = newUnitImage(tileInfo.civilianUnit, civilianUnitImage, isViewable, -20f)
|
||||||
militaryUnitImage = newUnitImage(tileInfo.militaryUnit, militaryUnitImage, isViewable, 20f)
|
militaryUnitImage = newUnitImage(tileInfo.militaryUnit, militaryUnitImage, isViewable && showSubmarine, 20f)
|
||||||
|
|
||||||
updateRoadImages()
|
updateRoadImages()
|
||||||
updateBorderImages()
|
updateBorderImages()
|
||||||
|
@ -23,7 +23,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun update(isViewable: Boolean) {
|
fun update(isViewable: Boolean, showSubmarine: Boolean) {
|
||||||
val city = tileInfo.getCity()
|
val city = tileInfo.getCity()
|
||||||
|
|
||||||
removePopulationIcon()
|
removePopulationIcon()
|
||||||
@ -36,7 +36,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
|
|||||||
updateCityButton(city, isViewable || UnCivGame.Current.viewEntireMapForDebug) // needs to be before the update so the units will be above the city button
|
updateCityButton(city, isViewable || UnCivGame.Current.viewEntireMapForDebug) // needs to be before the update so the units will be above the city button
|
||||||
|
|
||||||
super.update(isViewable || UnCivGame.Current.viewEntireMapForDebug,
|
super.update(isViewable || UnCivGame.Current.viewEntireMapForDebug,
|
||||||
UnCivGame.Current.settings.showResourcesAndImprovements)
|
UnCivGame.Current.settings.showResourcesAndImprovements, showSubmarine)
|
||||||
|
|
||||||
yieldGroup.isVisible = !UnCivGame.Current.settings.showResourcesAndImprovements
|
yieldGroup.isVisible = !UnCivGame.Current.settings.showResourcesAndImprovements
|
||||||
if (yieldGroup.isVisible)
|
if (yieldGroup.isVisible)
|
||||||
|
@ -180,6 +180,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
|||||||
|
|
||||||
internal fun updateTiles(civInfo: CivilizationInfo) {
|
internal fun updateTiles(civInfo: CivilizationInfo) {
|
||||||
val playerViewableTilePositions = civInfo.viewableTiles.map { it.position }.toHashSet()
|
val playerViewableTilePositions = civInfo.viewableTiles.map { it.position }.toHashSet()
|
||||||
|
val playerViewableInvisibleUnitsTilePositions = civInfo.viewableInvisibleUnitsTiles.map { it.position }.toHashSet()
|
||||||
|
|
||||||
cityButtonOverlays.forEach{it.remove()}
|
cityButtonOverlays.forEach{it.remove()}
|
||||||
cityButtonOverlays.clear()
|
cityButtonOverlays.clear()
|
||||||
@ -187,9 +188,16 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
|||||||
for (tileGroup in tileGroups.values){
|
for (tileGroup in tileGroups.values){
|
||||||
val canSeeTile = UnCivGame.Current.viewEntireMapForDebug
|
val canSeeTile = UnCivGame.Current.viewEntireMapForDebug
|
||||||
|| playerViewableTilePositions.contains(tileGroup.tileInfo.position)
|
|| playerViewableTilePositions.contains(tileGroup.tileInfo.position)
|
||||||
tileGroup.update(canSeeTile)
|
|
||||||
|
val showSubmarine = UnCivGame.Current.viewEntireMapForDebug
|
||||||
|
|| playerViewableInvisibleUnitsTilePositions.contains(tileGroup.tileInfo.position)
|
||||||
|
|| (!tileGroup.tileInfo.hasEnemySubmarine())
|
||||||
|
tileGroup.update(canSeeTile, showSubmarine)
|
||||||
|
|
||||||
val unitsInTile = tileGroup.tileInfo.getUnits()
|
val unitsInTile = tileGroup.tileInfo.getUnits()
|
||||||
if(canSeeTile && unitsInTile.isNotEmpty() && !unitsInTile.first().civInfo.isPlayerCivilization())
|
val canSeeEnemy = unitsInTile.isNotEmpty() && !unitsInTile.first().civInfo.isPlayerCivilization()
|
||||||
|
&& (showSubmarine || unitsInTile.firstOrNull {!it.isInvisible()}!=null)
|
||||||
|
if(canSeeTile && canSeeEnemy)
|
||||||
tileGroup.showCircle(Color.RED) // Display ALL viewable enemies with a red circle so that users don't need to go "hunting" for enemy units
|
tileGroup.showCircle(Color.RED) // Display ALL viewable enemies with a red circle so that users don't need to go "hunting" for enemy units
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user