mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-24 06:39:16 +07:00
Initial commit
This commit is contained in:
5
core/src/CivCity.gwt.xml
Normal file
5
core/src/CivCity.gwt.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit trunk//EN" "http://google-web-toolkit.googlecode.com/svn/trunk/distro-source/core/src/gwt-module.dtd">
|
||||
<module>
|
||||
<source path="com/unciv/game" />
|
||||
</module>
|
152
core/src/com/unciv/civinfo/CityBuildings.java
Normal file
152
core/src/com/unciv/civinfo/CityBuildings.java
Normal file
@ -0,0 +1,152 @@
|
||||
package com.unciv.civinfo;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Predicate;
|
||||
import com.unciv.game.UnCivGame;
|
||||
import com.unciv.models.gamebasics.Building;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.stats.FullStats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class CityBuildings
|
||||
{
|
||||
static final String Worker="Worker";
|
||||
static final String Settler="Settler";
|
||||
|
||||
public Vector2 cityLocation;
|
||||
|
||||
public CityBuildings(){} // for json parsing, we need to have a default constructor
|
||||
|
||||
public CityBuildings(CityInfo cityInfo)
|
||||
{
|
||||
cityLocation = cityInfo.cityLocation;
|
||||
}
|
||||
|
||||
public ArrayList<String> BuiltBuildings = new ArrayList<String>();
|
||||
public HashMap<String, Integer> InProgressBuildings = new HashMap<String, Integer>();
|
||||
public String CurrentBuilding = Worker; // default starting building!
|
||||
|
||||
public CityInfo GetCity(){return UnCivGame.Current.civInfo.tileMap.get(cityLocation).GetCity(); }
|
||||
public boolean IsBuilt(String buildingName) { return BuiltBuildings.contains(buildingName); }
|
||||
public boolean IsBuilding(String buildingName) { return CurrentBuilding.equals(buildingName); }
|
||||
|
||||
Building GetGameBuilding(String buildingName) { return GameBasics.Buildings.get(buildingName); }
|
||||
|
||||
public void NextTurn(int ProductionProduced)
|
||||
{
|
||||
if (CurrentBuilding == null) return;
|
||||
if (!InProgressBuildings.containsKey(CurrentBuilding)) InProgressBuildings.put(CurrentBuilding, 0);
|
||||
InProgressBuildings.put(CurrentBuilding, InProgressBuildings.get(CurrentBuilding) + ProductionProduced);
|
||||
|
||||
if (InProgressBuildings.get(CurrentBuilding) >= GetGameBuilding(CurrentBuilding).Cost)
|
||||
{
|
||||
if (CurrentBuilding.equals(Worker) || CurrentBuilding.equals(Settler))
|
||||
UnCivGame.Current.civInfo.tileMap.get(cityLocation).Unit = new Unit(CurrentBuilding,2);
|
||||
|
||||
else
|
||||
{
|
||||
BuiltBuildings.add(CurrentBuilding);
|
||||
Building gameBuilding = GetGameBuilding(CurrentBuilding);
|
||||
if (gameBuilding.ProvidesFreeBuilding != null && !BuiltBuildings.contains(gameBuilding.ProvidesFreeBuilding))
|
||||
BuiltBuildings.add(gameBuilding.ProvidesFreeBuilding);
|
||||
if (gameBuilding.FreeTechs != 0) UnCivGame.Current.civInfo.Tech.FreeTechs += gameBuilding.FreeTechs;
|
||||
}
|
||||
|
||||
InProgressBuildings.remove(CurrentBuilding);
|
||||
|
||||
// Choose next building to build
|
||||
CurrentBuilding = GetBuildableBuildings().first(new Predicate<String>() {
|
||||
@Override
|
||||
public boolean evaluate(String arg0) {
|
||||
if(arg0.equals(Settler) || arg0.equals(Worker)) return false;
|
||||
return !BuiltBuildings.contains(arg0);
|
||||
}
|
||||
});
|
||||
if (CurrentBuilding == null) CurrentBuilding = Worker;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean CanBuild(final Building building)
|
||||
{
|
||||
CivilizationInfo civInfo = UnCivGame.Current.civInfo;
|
||||
if(IsBuilt(building.Name)) return false;
|
||||
// if (building.Name.equals("Worker") || building.Name.equals("Settler")) return false;
|
||||
if(building.ResourceRequired) {
|
||||
boolean containsResourceWithImprovement = GetCity().GetCityTiles()
|
||||
.any(new Predicate<TileInfo>() {
|
||||
@Override
|
||||
public boolean evaluate(TileInfo tile) {
|
||||
return tile.Resource != null
|
||||
&& building.Name.equals(tile.GetTileResource().Building)
|
||||
&& tile.GetTileResource().Improvement.equals(tile.Improvement);
|
||||
}
|
||||
});
|
||||
if(!containsResourceWithImprovement) return false;
|
||||
}
|
||||
|
||||
if (building.RequiredTech != null && !civInfo.Tech.IsResearched(building.RequiredTech)) return false;
|
||||
if (building.IsWonder && civInfo.Cities
|
||||
.any(new Predicate<CityInfo>() {
|
||||
@Override
|
||||
public boolean evaluate(CityInfo arg0) {
|
||||
CityBuildings CB = arg0.cityBuildings;
|
||||
return CB.IsBuilt(building.Name) || CB.IsBuilt(building.Name);
|
||||
}
|
||||
}) ) return false;
|
||||
if (building.RequiredBuilding != null && !IsBuilt(building.RequiredBuilding)) return false;
|
||||
if (building.RequiredBuildingInAllCities != null ||
|
||||
civInfo.Cities.any(new Predicate<CityInfo>() {
|
||||
@Override
|
||||
public boolean evaluate(CityInfo arg0) {
|
||||
return arg0.cityBuildings.IsBuilt(building.RequiredBuildingInAllCities);
|
||||
}
|
||||
}) ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public com.unciv.models.LinqCollection<String> GetBuildableBuildings()
|
||||
{
|
||||
return new com.unciv.models.LinqCollection<Building>(GameBasics.Buildings.values())
|
||||
.where(new Predicate<Building>() {
|
||||
@Override
|
||||
public boolean evaluate(Building arg0) { return CanBuild(arg0); }
|
||||
})
|
||||
.select(new com.unciv.models.LinqCollection.Func<Building, String>() {
|
||||
@Override
|
||||
public String GetBy(Building arg0) {
|
||||
return arg0.Name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public FullStats GetStats()
|
||||
{
|
||||
FullStats stats = new FullStats();
|
||||
for (String building : BuiltBuildings)
|
||||
{
|
||||
Building gameBuilding = GetGameBuilding(building);
|
||||
stats.add(gameBuilding);
|
||||
//if (gameBuilding.GetFlatBonusStats != null) stats.add(gameBuilding.GetFlatBonusStats(cityInfo));
|
||||
stats.Gold -= gameBuilding.Maintainance;
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
public int TurnsToBuilding(String buildingName)
|
||||
{
|
||||
int workDone = 0;
|
||||
if (InProgressBuildings.containsKey(buildingName)) workDone = InProgressBuildings.get(buildingName);
|
||||
float workLeft = GetGameBuilding(buildingName).Cost - workDone; // needs to be float so that we get the cieling properly ;)
|
||||
|
||||
FullStats cityStats = GetCity().getCityStats();
|
||||
int production = cityStats.Production;
|
||||
if (buildingName.equals(Settler)) production += cityStats.Food;
|
||||
|
||||
return (int) Math.ceil(workLeft / production);
|
||||
}
|
||||
}
|
132
core/src/com/unciv/civinfo/CityInfo.java
Normal file
132
core/src/com/unciv/civinfo/CityInfo.java
Normal file
@ -0,0 +1,132 @@
|
||||
package com.unciv.civinfo;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Predicate;
|
||||
import com.unciv.game.HexMath;
|
||||
import com.unciv.game.UnCivGame;
|
||||
import com.unciv.models.LinqCollection;
|
||||
import com.unciv.models.stats.FullStats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CityInfo {
|
||||
public final Vector2 cityLocation;
|
||||
public String Name;
|
||||
|
||||
public CityBuildings cityBuildings;
|
||||
public CityPopulation cityPopulation;
|
||||
|
||||
public LinqCollection<Vector2> CityTileLocations = new LinqCollection<Vector2>();
|
||||
|
||||
public LinqCollection<TileInfo> GetCityTiles(){
|
||||
return CityTileLocations.select(new com.unciv.models.LinqCollection.Func<Vector2, TileInfo>() {
|
||||
@Override
|
||||
public TileInfo GetBy(Vector2 arg0) {
|
||||
return UnCivGame.Current.civInfo.tileMap.get(arg0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String[] CityNames = new String[]{"Assur", "Ninveh", "Nimrud", "Kar-Tukuli-Ninurta", "Dur-Sharrukin"};
|
||||
|
||||
public CityInfo(){
|
||||
cityLocation = Vector2.Zero;
|
||||
} // for json parsing, we need to have a default constructor
|
||||
|
||||
public CityInfo(CivilizationInfo civInfo, Vector2 cityLocation) {
|
||||
Name = CityNames[civInfo.Cities.size()];
|
||||
this.cityLocation = cityLocation;
|
||||
cityBuildings = new CityBuildings(this);
|
||||
cityPopulation = new CityPopulation();
|
||||
|
||||
for(Vector2 vector : HexMath.GetVectorsInDistance(cityLocation,2))
|
||||
{
|
||||
if(civInfo.tileMap.get(vector).GetCity() == null)
|
||||
CityTileLocations.add(vector);
|
||||
}
|
||||
|
||||
AutoAssignWorker();
|
||||
civInfo.Cities.add(this);
|
||||
}
|
||||
|
||||
public ArrayList<String> GetLuxuryResources() {
|
||||
ArrayList<String> LuxuryResources = new ArrayList<String>();
|
||||
for (TileInfo tileInfo : GetCityTiles()) {
|
||||
com.unciv.models.gamebasics.TileResource resource = tileInfo.GetTileResource();
|
||||
if (resource != null && resource.ResourceType.equals("Luxury") && resource.Improvement.equals(tileInfo.Improvement))
|
||||
LuxuryResources.add(tileInfo.Resource);
|
||||
}
|
||||
return LuxuryResources;
|
||||
}
|
||||
|
||||
|
||||
public int GetWorkingPopulation() {
|
||||
return GetCityTiles().count(new Predicate<TileInfo>() {
|
||||
@Override
|
||||
public boolean evaluate(TileInfo arg0) {
|
||||
return arg0.IsWorked;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int GetFreePopulation() {
|
||||
return cityPopulation.Population - GetWorkingPopulation();
|
||||
}
|
||||
|
||||
public boolean HasNonWorkingPopulation() {
|
||||
return GetFreePopulation() > 0;
|
||||
}
|
||||
|
||||
public FullStats getCityStats() {
|
||||
FullStats stats = new FullStats() {{
|
||||
Happiness = -3 - cityPopulation.Population; // -3 happiness per city and -3 per population
|
||||
}};
|
||||
|
||||
stats.Science += cityPopulation.Population;
|
||||
|
||||
// Working ppl
|
||||
for (TileInfo cell : GetCityTiles()) {
|
||||
if (cell.IsWorked || cell.IsCityCenter()) stats.add(cell.GetTileStats());
|
||||
}
|
||||
//idle ppl
|
||||
stats.Production += GetFreePopulation();
|
||||
stats.Food -= cityPopulation.Population * 2;
|
||||
|
||||
stats.add(cityBuildings.GetStats());
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
public void NextTurn() {
|
||||
FullStats stats = getCityStats();
|
||||
|
||||
if (cityBuildings.CurrentBuilding.equals(cityBuildings.Settler) && stats.Food > 0) {
|
||||
stats.Production += stats.Food;
|
||||
stats.Food = 0;
|
||||
}
|
||||
|
||||
if (cityPopulation.NextTurn(stats.Food)) AutoAssignWorker();
|
||||
|
||||
cityBuildings.NextTurn(stats.Production);
|
||||
|
||||
for (TileInfo tileInfo : GetCityTiles()) {
|
||||
tileInfo.NextTurn();
|
||||
}
|
||||
}
|
||||
|
||||
public void AutoAssignWorker() {
|
||||
double maxValue = 0;
|
||||
TileInfo toWork = null;
|
||||
for (TileInfo tileInfo : GetCityTiles()) {
|
||||
if (tileInfo.IsWorked || tileInfo.IsCityCenter()) continue;
|
||||
FullStats stats = tileInfo.GetTileStats();
|
||||
|
||||
double value = stats.Food + stats.Production * 0.5;
|
||||
if (value > maxValue) {
|
||||
maxValue = value;
|
||||
toWork = tileInfo;
|
||||
}
|
||||
}
|
||||
toWork.IsWorked = true;
|
||||
}
|
||||
}
|
34
core/src/com/unciv/civinfo/CityPopulation.java
Normal file
34
core/src/com/unciv/civinfo/CityPopulation.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.unciv.civinfo;
|
||||
|
||||
public class CityPopulation
|
||||
{
|
||||
public int Population = 1;
|
||||
public int FoodStored = 0;
|
||||
public int FoodToNextPopulation()
|
||||
{
|
||||
// civ v math,civilization.wikia
|
||||
return 15 + 6 * (Population - 1) + (int)Math.floor(Math.pow(Population - 1, 1.8f));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FoodProduced
|
||||
* @return whether a growth occured
|
||||
*/
|
||||
public boolean NextTurn(int FoodProduced)
|
||||
{
|
||||
FoodStored += FoodProduced;
|
||||
if (FoodStored < 0) // starvation!
|
||||
{
|
||||
Population--;
|
||||
FoodStored = 0;
|
||||
}
|
||||
if (FoodStored >= FoodToNextPopulation()) // growth!
|
||||
{
|
||||
FoodStored -= FoodToNextPopulation();
|
||||
Population++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
71
core/src/com/unciv/civinfo/CivilizationInfo.java
Normal file
71
core/src/com/unciv/civinfo/CivilizationInfo.java
Normal file
@ -0,0 +1,71 @@
|
||||
package com.unciv.civinfo;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.unciv.game.pickerscreens.GameSaver;
|
||||
import com.unciv.models.LinqCollection;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.stats.CivStats;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Created by LENOVO on 10/18/2017.
|
||||
*/
|
||||
public class CivilizationInfo {
|
||||
|
||||
public CivStats civStats = new CivStats();
|
||||
public int baseHappiness = 15;
|
||||
|
||||
public CivilizationTech Tech = new CivilizationTech();
|
||||
public int turns = 1;
|
||||
|
||||
public LinqCollection<CityInfo> Cities = new LinqCollection<CityInfo>();
|
||||
|
||||
public TileMap tileMap = new TileMap(20);
|
||||
|
||||
public int CurrentCity=0; //index!
|
||||
|
||||
public CivilizationInfo(){
|
||||
}
|
||||
|
||||
|
||||
public CityInfo GetCurrentCity() { return Cities.get(CurrentCity); }
|
||||
|
||||
public int TurnsToTech(String TechName) {
|
||||
return (int) Math.ceil((float)(GameBasics.Technologies.get(TechName).Cost - Tech.ResearchOfTech(TechName))
|
||||
/ GetStatsForNextTurn().Science);
|
||||
}
|
||||
|
||||
public void addCity(Vector2 location){
|
||||
CityInfo city = new CityInfo(this,location);
|
||||
if(Cities.size()==1) city.cityBuildings.BuiltBuildings.add("Palace");
|
||||
}
|
||||
|
||||
public void NextTurn()//out boolean displayTech)
|
||||
{
|
||||
CivStats nextTurnStats = GetStatsForNextTurn();
|
||||
civStats.add(nextTurnStats);
|
||||
if(Cities.size() > 0) Tech.NextTurn(nextTurnStats.Science);
|
||||
|
||||
for (CityInfo city : Cities.as(CityInfo.class)) city.NextTurn();
|
||||
|
||||
for(TileInfo tile : tileMap.values()) if(tile.Unit!=null) tile.Unit.CurrentMovement = tile.Unit.MaxMovement;
|
||||
|
||||
turns += 1;
|
||||
}
|
||||
|
||||
public CivStats GetStatsForNextTurn() {
|
||||
CivStats statsForTurn = new CivStats() {{
|
||||
Happiness = baseHappiness;
|
||||
}};
|
||||
HashSet<String> LuxuryResources = new HashSet<String>();
|
||||
for (CityInfo city : Cities) {
|
||||
statsForTurn.add(city.getCityStats());
|
||||
LuxuryResources.addAll(city.GetLuxuryResources());
|
||||
}
|
||||
statsForTurn.Happiness += LuxuryResources.size() * 5; // 5 happiness for each unique luxury in civ
|
||||
|
||||
return statsForTurn;
|
||||
}
|
||||
}
|
||||
|
55
core/src/com/unciv/civinfo/CivilizationTech.java
Normal file
55
core/src/com/unciv/civinfo/CivilizationTech.java
Normal file
@ -0,0 +1,55 @@
|
||||
package com.unciv.civinfo;
|
||||
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.gamebasics.Technology;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CivilizationTech{
|
||||
public int FreeTechs = 0;
|
||||
|
||||
public ArrayList<String> TechsResearched = new ArrayList<String>();
|
||||
/* When moving towards a certain tech, the user doesn't have to manually pick every one. */
|
||||
public ArrayList<String> TechsToResearch = new ArrayList<String>();
|
||||
public HashMap<String, Integer> TechsInProgress = new HashMap<String, Integer>();
|
||||
|
||||
public String CurrentTechnology(){if(TechsToResearch.isEmpty()) return null; return TechsToResearch.get(0);}
|
||||
|
||||
public Technology GetCurrentTechnology() {
|
||||
return GameBasics.Technologies.get(CurrentTechnology());
|
||||
}
|
||||
|
||||
public int ResearchOfTech(String TechName) {
|
||||
int amountResearched = 0;
|
||||
if (TechsInProgress.containsKey(TechName)) amountResearched = TechsInProgress.get(TechName);
|
||||
return amountResearched;
|
||||
}
|
||||
|
||||
|
||||
public boolean IsResearched(String TechName) {
|
||||
return TechsResearched.contains(TechName);
|
||||
}
|
||||
|
||||
public boolean CanBeResearched(String TechName) {
|
||||
for (String prerequisiteTech : GameBasics.Technologies.get(TechName).Prerequisites)
|
||||
if (!IsResearched(prerequisiteTech)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void NextTurn(int scienceForNewTurn){
|
||||
|
||||
String CurrentTechnology = CurrentTechnology();
|
||||
|
||||
if (!TechsInProgress.containsKey(CurrentTechnology))
|
||||
TechsInProgress.put(CurrentTechnology, 0);
|
||||
TechsInProgress.put(CurrentTechnology, TechsInProgress.get(CurrentTechnology) + scienceForNewTurn);
|
||||
if (TechsInProgress.get(CurrentTechnology) >= GetCurrentTechnology().Cost) // We finished it!
|
||||
{
|
||||
TechsInProgress.remove(CurrentTechnology);
|
||||
TechsResearched.add(CurrentTechnology);
|
||||
TechsToResearch.remove(CurrentTechnology);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
134
core/src/com/unciv/civinfo/TileInfo.java
Normal file
134
core/src/com/unciv/civinfo/TileInfo.java
Normal file
@ -0,0 +1,134 @@
|
||||
package com.unciv.civinfo;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Predicate;
|
||||
import com.unciv.game.UnCivGame;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.gamebasics.Terrain;
|
||||
import com.unciv.models.gamebasics.TileImprovement;
|
||||
import com.unciv.models.gamebasics.TileResource;
|
||||
import com.unciv.models.stats.FullStats;
|
||||
|
||||
public class TileInfo
|
||||
{
|
||||
public Unit Unit;
|
||||
public Vector2 Position;
|
||||
public String BaseTerrain;
|
||||
public String TerrainFeature;
|
||||
public String Resource;
|
||||
public boolean IsWorked = false;
|
||||
public String Improvement;
|
||||
public String ImprovementInProgress;
|
||||
public int TurnsToImprovement;
|
||||
|
||||
public Terrain GetBaseTerrain(){return GameBasics.Terrains.get(BaseTerrain);}
|
||||
public CityInfo GetCity(){return UnCivGame.Current.civInfo.Cities.first(new Predicate<CityInfo>() {
|
||||
@Override
|
||||
public boolean evaluate(CityInfo arg0) {
|
||||
return arg0.CityTileLocations.contains(Position);
|
||||
}
|
||||
});}
|
||||
|
||||
public Terrain GetTerrainFeature(){return TerrainFeature==null ? null : GameBasics.Terrains.get(TerrainFeature);}
|
||||
|
||||
public Terrain GetLastTerrain() {
|
||||
return TerrainFeature == null ? GetBaseTerrain() : GetTerrainFeature();
|
||||
}
|
||||
|
||||
public TileResource GetTileResource(){return Resource==null ? null : GameBasics.TileResources.get(Resource);}
|
||||
|
||||
public boolean IsCityCenter(){return GetCity()!=null && Position.equals(GetCity().cityLocation);}
|
||||
|
||||
public TileImprovement GetTileImprovement(){return Improvement==null ? null : GameBasics.TileImprovements.get(Improvement);}
|
||||
|
||||
|
||||
private boolean IsResearched(String techName) { return UnCivGame.Current.civInfo.Tech.IsResearched(techName); }
|
||||
|
||||
public FullStats GetTileStats()
|
||||
{
|
||||
FullStats stats = new FullStats(GetBaseTerrain());
|
||||
|
||||
if(TerrainFeature!=null){
|
||||
Terrain terrainFeature = GetTerrainFeature();
|
||||
if(terrainFeature.OverrideStats) stats = new FullStats(terrainFeature);
|
||||
else stats.add(terrainFeature);
|
||||
}
|
||||
|
||||
TileResource resource = GetTileResource();
|
||||
|
||||
CityInfo City = GetCity();
|
||||
if (HasViewableResource())
|
||||
{
|
||||
stats.add(resource);
|
||||
if(resource.Building!=null && City!=null && City.cityBuildings.IsBuilt(resource.Building))
|
||||
{
|
||||
stats.add(resource.GetBuilding().ResourceBonusStats);
|
||||
}
|
||||
}
|
||||
|
||||
TileImprovement improvement = GetTileImprovement();
|
||||
if (improvement != null)
|
||||
{
|
||||
if (resource != null && resource.Improvement.equals(improvement.Name))
|
||||
stats.add(resource.ImprovementStats);
|
||||
else stats.add(improvement);
|
||||
|
||||
if (IsResearched(improvement.ImprovingTech)) stats.add(improvement.ImprovingTechStats);
|
||||
}
|
||||
|
||||
if (City != null && City.cityLocation.equals(Position)) {
|
||||
if (stats.Food < 2) stats.Food = 2;
|
||||
if (stats.Production < 1) stats.Production = 1;
|
||||
}
|
||||
if (stats.Production < 0) stats.Production = 0;
|
||||
return stats;
|
||||
}
|
||||
|
||||
public boolean CanBuildImprovement(TileImprovement improvement)
|
||||
{
|
||||
Terrain topTerrain = TerrainFeature==null ? GetBaseTerrain() : GetTerrainFeature();
|
||||
if (improvement.TechRequired != null && !IsResearched(improvement.TechRequired)) return false;
|
||||
if (improvement.TerrainsCanBeBuiltOn.contains(topTerrain.Name)) return true;
|
||||
if (topTerrain.Unbuildable) return false;
|
||||
return Resource != null && GetTileResource().Improvement.equals(improvement.Name);
|
||||
}
|
||||
|
||||
public void StartWorkingOnImprovement(TileImprovement improvement)
|
||||
{
|
||||
ImprovementInProgress = improvement.Name;
|
||||
TurnsToImprovement = improvement.TurnsToBuild;
|
||||
}
|
||||
|
||||
public void StopWorkingOnImprovement()
|
||||
{
|
||||
ImprovementInProgress = null;
|
||||
}
|
||||
|
||||
public void NextTurn()
|
||||
{
|
||||
if (ImprovementInProgress == null || Unit==null || !Unit.Name.equals("Worker")) return;
|
||||
TurnsToImprovement -= 1;
|
||||
if(TurnsToImprovement == 0)
|
||||
{
|
||||
if (ImprovementInProgress.startsWith("Remove")) TerrainFeature = null;
|
||||
else Improvement = ImprovementInProgress;
|
||||
|
||||
ImprovementInProgress = null;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder SB = new StringBuilder(this.BaseTerrain);
|
||||
if (TerrainFeature != null) SB.append(",\r\n" + TerrainFeature);
|
||||
if (HasViewableResource()) SB.append(",\r\n" + Resource);
|
||||
if (Improvement != null) SB.append(",\r\n" + Improvement);
|
||||
if (ImprovementInProgress != null) SB.append(",\r\n" + ImprovementInProgress+" in "+this.TurnsToImprovement+" turns");
|
||||
if(Unit!=null) SB.append(",\r\n" + Unit.Name+ "("+Unit.CurrentMovement+"/"+Unit.MaxMovement+")");
|
||||
return SB.toString();
|
||||
}
|
||||
|
||||
public boolean HasViewableResource() {
|
||||
return Resource != null && (GetTileResource().RevealedBy==null || IsResearched(GetTileResource().RevealedBy));
|
||||
}
|
||||
|
||||
}
|
89
core/src/com/unciv/civinfo/TileMap.java
Normal file
89
core/src/com/unciv/civinfo/TileMap.java
Normal file
@ -0,0 +1,89 @@
|
||||
package com.unciv.civinfo;
|
||||
|
||||
import com.badlogic.gdx.math.Vector;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Predicate;
|
||||
import com.unciv.game.HexMath;
|
||||
import com.unciv.models.LinqCollection;
|
||||
import com.unciv.models.LinqHashMap;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.gamebasics.Terrain;
|
||||
import com.unciv.models.gamebasics.TileResource;
|
||||
|
||||
public class TileMap{
|
||||
|
||||
private LinqHashMap<String, TileInfo> tiles = new LinqHashMap<String, TileInfo>();
|
||||
|
||||
public TileMap(){} // for json parsing, we need to have a default constructor
|
||||
|
||||
public TileMap(int distance) {
|
||||
for(Vector2 vector : HexMath.GetVectorsInDistance(Vector2.Zero,distance)) addRandomTile(vector);
|
||||
}
|
||||
|
||||
|
||||
private void addRandomTile(Vector2 position) {
|
||||
final TileInfo tileInfo = new TileInfo();
|
||||
tileInfo.Position = position;
|
||||
LinqCollection<Terrain> Terrains = GameBasics.Terrains.linqValues();
|
||||
|
||||
final Terrain baseTerrain = Terrains.where(new Predicate<Terrain>() {
|
||||
@Override
|
||||
public boolean evaluate(Terrain arg0) {
|
||||
return arg0.Type.equals("BaseTerrain") && !arg0.Name.equals("Lakes");
|
||||
}
|
||||
}).getRandom();
|
||||
tileInfo.BaseTerrain = baseTerrain.Name;
|
||||
|
||||
if (baseTerrain.CanHaveOverlay) {
|
||||
if (Math.random() > 0.7f) {
|
||||
Terrain SecondaryTerrain = Terrains.where(new Predicate<Terrain>() {
|
||||
@Override
|
||||
public boolean evaluate(Terrain arg0) {
|
||||
return arg0.Type.equals("TerrainFeature") && arg0.OccursOn.contains(baseTerrain.Name);
|
||||
}
|
||||
}).getRandom();
|
||||
if (SecondaryTerrain != null) tileInfo.TerrainFeature = SecondaryTerrain.Name;
|
||||
}
|
||||
}
|
||||
|
||||
LinqCollection<TileResource> TileResources = GameBasics.TileResources.linqValues();
|
||||
|
||||
// Resources are placed according to TerrainFeature, if exists, otherwise according to BaseLayer.
|
||||
TileResources = TileResources.where(new Predicate<TileResource>() {
|
||||
@Override
|
||||
public boolean evaluate(TileResource arg0) {
|
||||
return arg0.TerrainsCanBeFoundOn.contains(tileInfo.GetLastTerrain().Name);
|
||||
}
|
||||
});
|
||||
|
||||
TileResource resource = null;
|
||||
if (Math.random() < 1 / 5f) {
|
||||
resource = GetRandomResource(TileResources, "Bonus");
|
||||
} else if (Math.random() < 1 / 7f) {
|
||||
resource = GetRandomResource(TileResources, "Strategic");
|
||||
} else if (Math.random() < 1 / 10f) {
|
||||
resource = GetRandomResource(TileResources, "Luxury");
|
||||
}
|
||||
if (resource != null) tileInfo.Resource = resource.Name;
|
||||
|
||||
// tileInfo.City = this;
|
||||
// GetCityTiles.put(vector2, tileInfo);
|
||||
tiles.put(position.toString(),tileInfo);
|
||||
}
|
||||
|
||||
public boolean contains(Vector2 vector){ return tiles.containsKey(vector.toString());}
|
||||
|
||||
public TileInfo get(Vector2 vector){return tiles.get(vector.toString());}
|
||||
|
||||
public LinqCollection<TileInfo> values(){return tiles.linqValues();}
|
||||
|
||||
public TileResource GetRandomResource(LinqCollection<TileResource> resources, final String resourceType) {
|
||||
return resources.where(new Predicate<TileResource>() {
|
||||
@Override
|
||||
public boolean evaluate(TileResource arg0) {
|
||||
return arg0.ResourceType.equals(resourceType);
|
||||
}
|
||||
}).getRandom();
|
||||
}
|
||||
|
||||
}
|
15
core/src/com/unciv/civinfo/Unit.java
Normal file
15
core/src/com/unciv/civinfo/Unit.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.unciv.civinfo;
|
||||
|
||||
public class Unit{
|
||||
public String Name;
|
||||
public int MaxMovement;
|
||||
public int CurrentMovement;
|
||||
|
||||
public Unit(){} // for json parsing, we need to have a default constructor
|
||||
|
||||
public Unit(String name, int maxMovement) {
|
||||
Name = name;
|
||||
MaxMovement = maxMovement;
|
||||
CurrentMovement = maxMovement;
|
||||
}
|
||||
}
|
72
core/src/com/unciv/game/CameraStageBaseScreen.java
Normal file
72
core/src/com/unciv/game/CameraStageBaseScreen.java
Normal file
@ -0,0 +1,72 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
import com.badlogic.gdx.utils.viewport.FitViewport;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CameraStageBaseScreen implements Screen {
|
||||
|
||||
protected UnCivGame game;
|
||||
protected Stage stage;
|
||||
protected Skin skin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
|
||||
static Batch batch = new SpriteBatch();
|
||||
|
||||
|
||||
public CameraStageBaseScreen(UnCivGame game) {
|
||||
this.game = game;
|
||||
stage = new Stage(new FitViewport(1000,600),batch);
|
||||
Gdx.input.setInputProcessor(stage);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
stage.act();
|
||||
stage.draw();;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height) {
|
||||
stage.getViewport().update(width,height,true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
299
core/src/com/unciv/game/CityScreen.java
Normal file
299
core/src/com/unciv/game/CityScreen.java
Normal file
@ -0,0 +1,299 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.Pixmap.Blending;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
|
||||
import com.unciv.civinfo.CityInfo;
|
||||
import com.unciv.civinfo.TileInfo;
|
||||
import com.unciv.game.pickerscreens.BuildingPickerScreen;
|
||||
import com.unciv.models.stats.FullStats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class CityScreen extends CameraStageBaseScreen {
|
||||
|
||||
TileInfo selectedTile = null;
|
||||
float buttonScale = game.settings.buttonScale;
|
||||
Table TileTable = new Table();
|
||||
Table CityStatsTable = new Table();
|
||||
Table CityPickerTable = new Table();
|
||||
TextButton TechButton = new TextButton("Exit city",skin);
|
||||
public ArrayList<TileGroup> tileGroups = new ArrayList<TileGroup>();
|
||||
|
||||
public CityScreen(final UnCivGame game) {
|
||||
super(game);
|
||||
new Label("",skin).getStyle().font.getData().setScale(game.settings.labelScale);
|
||||
|
||||
addTiles();
|
||||
stage.addActor(TileTable);
|
||||
|
||||
|
||||
Drawable tileTableBackground = new TextureRegionDrawable(new TextureRegion(new Texture("skin/tileTableBackground.png")))
|
||||
.tint(new Color(0x0040804f));
|
||||
tileTableBackground.setMinHeight(0);
|
||||
tileTableBackground.setMinWidth(0);
|
||||
TileTable.setBackground(tileTableBackground);
|
||||
|
||||
CityStatsTable.setBackground(tileTableBackground);
|
||||
updateCityTable();
|
||||
stage.addActor(CityStatsTable);
|
||||
|
||||
updateGoToWorldButton();
|
||||
stage.addActor(TechButton);
|
||||
|
||||
updateCityPickerTable();
|
||||
stage.addActor(CityPickerTable);
|
||||
}
|
||||
|
||||
private void updateCityPickerTable() {
|
||||
CityPickerTable.clear();
|
||||
CityPickerTable.row().pad(20);
|
||||
if(game.civInfo.Cities.size()>1) {
|
||||
TextButton prevCityButton = new TextButton("<", skin);
|
||||
prevCityButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
com.unciv.civinfo.CivilizationInfo ci = game.civInfo;
|
||||
if (ci.CurrentCity == 0) ci.CurrentCity = ci.Cities.size()-1;
|
||||
else ci.CurrentCity--;
|
||||
game.setScreen(new CityScreen(game));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
CityPickerTable.add(prevCityButton);
|
||||
}
|
||||
|
||||
Label currentCityLabel = new Label(game.civInfo.GetCurrentCity().Name, skin);
|
||||
currentCityLabel.setFontScale(2);
|
||||
CityPickerTable.add(currentCityLabel);
|
||||
|
||||
if(game.civInfo.Cities.size()>1) {
|
||||
TextButton nextCityButton = new TextButton(">", skin);
|
||||
nextCityButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
com.unciv.civinfo.CivilizationInfo ci = game.civInfo;
|
||||
if (ci.CurrentCity == ci.Cities.size()-1) ci.CurrentCity = 0;
|
||||
else ci.CurrentCity++;
|
||||
game.setScreen(new CityScreen(game));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
CityPickerTable.add(nextCityButton);
|
||||
}
|
||||
CityPickerTable.pack();
|
||||
CityPickerTable.setPosition(stage.getWidth()/2-CityPickerTable.getWidth()/2,0);
|
||||
stage.addActor(CityPickerTable);
|
||||
}
|
||||
|
||||
private void updateGoToWorldButton() {
|
||||
TechButton.clearListeners();
|
||||
TechButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setWorldScreen();
|
||||
game.worldScreen.setCenterPosition(game.civInfo.GetCurrentCity().cityLocation);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
||||
TechButton.setSize(TechButton.getPrefWidth(), TechButton.getPrefHeight());
|
||||
TechButton.setPosition(10, stage.getHeight() - TechButton.getHeight()-5);
|
||||
}
|
||||
|
||||
private void addTiles() {
|
||||
final CityInfo cityInfo = game.civInfo.GetCurrentCity();
|
||||
|
||||
Group allTiles = new Group();
|
||||
|
||||
for(Vector2 vector : HexMath.GetVectorsInDistance(cityInfo.cityLocation,5)){
|
||||
final TileInfo tileInfo = game.civInfo.tileMap.get(vector);
|
||||
TileGroup group = new TileGroup(tileInfo);
|
||||
group.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
selectedTile = tileInfo;
|
||||
updateTileTable();
|
||||
}
|
||||
});
|
||||
|
||||
if(!cityInfo.GetCityTiles().contains(tileInfo)) group.setColor(0,0,0,0.3f);
|
||||
else if(!tileInfo.IsCityCenter()) {
|
||||
group.addPopulationIcon();
|
||||
group.populationImage.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
if (cityInfo.GetFreePopulation() > 0 || tileInfo.IsWorked)
|
||||
tileInfo.IsWorked = !tileInfo.IsWorked;
|
||||
updateCityTable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Vector2 positionalVector = HexMath.Hex2WorldCoords(vector.cpy().sub(cityInfo.cityLocation));
|
||||
int groupSize = 50;
|
||||
group.setPosition(stage.getWidth()/2 + positionalVector.x*0.8f * groupSize,
|
||||
stage.getHeight()/2 + positionalVector.y*0.8f * groupSize);
|
||||
tileGroups.add(group);
|
||||
allTiles.addActor(group);
|
||||
}
|
||||
|
||||
final ScrollPane scrollPane = new ScrollPane(allTiles);
|
||||
scrollPane.setFillParent(true);
|
||||
scrollPane.setPosition(game.settings.cityTilesX, game.settings.cityTilesY);
|
||||
scrollPane.setOrigin(stage.getWidth()/2,stage.getHeight()/2);
|
||||
scrollPane.setScale(game.settings.tilesZoom);
|
||||
scrollPane.addListener(new ActorGestureListener(){
|
||||
public float lastScale =1;
|
||||
float lastInitialDistance=0;
|
||||
|
||||
@Override
|
||||
public void zoom(InputEvent event, float initialDistance, float distance) {
|
||||
if(lastInitialDistance!=initialDistance){
|
||||
lastInitialDistance = initialDistance;
|
||||
lastScale = scrollPane.getScaleX();
|
||||
}
|
||||
float scale = (float) Math.sqrt(distance/initialDistance)* lastScale;
|
||||
scrollPane.setScale(scale);
|
||||
game.settings.tilesZoom=scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pan(InputEvent event, float x, float y, float deltaX, float deltaY) {
|
||||
scrollPane.moveBy(deltaX*scrollPane.getScaleX(),deltaY*scrollPane.getScaleX());
|
||||
game.settings.cityTilesX = scrollPane.getX();
|
||||
game.settings.cityTilesY = scrollPane.getY();
|
||||
}
|
||||
});
|
||||
stage.addActor(scrollPane);
|
||||
}
|
||||
|
||||
private void updateCityTable() {
|
||||
CityInfo cityInfo = game.civInfo.GetCurrentCity();
|
||||
FullStats stats = cityInfo.getCityStats();
|
||||
CityStatsTable.pad(20);
|
||||
CityStatsTable.columnDefaults(0).padRight(10);
|
||||
CityStatsTable.clear();
|
||||
|
||||
Label cityStatsHeader = new Label("City Stats",skin);
|
||||
|
||||
cityStatsHeader.setFontScale(2);
|
||||
CityStatsTable.add(cityStatsHeader).colspan(2).pad(10);
|
||||
CityStatsTable.row();
|
||||
|
||||
HashMap<String,String> CityStatsValues = new LinkedHashMap<String, String>();
|
||||
CityStatsValues.put("Production",stats.Production+"");
|
||||
CityStatsValues.put("Food",stats.Food+" ("+cityInfo.cityPopulation.FoodStored+"/"+cityInfo.cityPopulation.FoodToNextPopulation()+")");
|
||||
CityStatsValues.put("Gold",stats.Gold+"");
|
||||
CityStatsValues.put("Science",stats.Science+"");
|
||||
CityStatsValues.put("Culture",stats.Culture+"");
|
||||
CityStatsValues.put("Population",cityInfo.GetFreePopulation()+"/"+cityInfo.cityPopulation.Population);
|
||||
|
||||
for(String key : CityStatsValues.keySet()){
|
||||
CityStatsTable.add(ImageGetter.getStatIcon(key)).align(Align.right);
|
||||
CityStatsTable.add(new Label(CityStatsValues.get(key),skin)).align(Align.left);
|
||||
CityStatsTable.row();
|
||||
}
|
||||
|
||||
String CurrentBuilding = game.civInfo.GetCurrentCity().cityBuildings.CurrentBuilding;
|
||||
|
||||
String BuildingText = "Pick building";
|
||||
if(CurrentBuilding != null) BuildingText = CurrentBuilding+"\r\n"
|
||||
+cityInfo.cityBuildings.TurnsToBuilding(CurrentBuilding)+" turns";
|
||||
TextButton buildingPickButton = new TextButton(BuildingText,skin);
|
||||
buildingPickButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setScreen(new BuildingPickerScreen(game));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
buildingPickButton.getLabel().setFontScale(buttonScale);
|
||||
CityStatsTable.add(buildingPickButton).colspan(2).pad(10)
|
||||
.size(buildingPickButton.getWidth()*buttonScale,buildingPickButton.getHeight()*buttonScale);
|
||||
|
||||
CityStatsTable.setPosition(10,10);
|
||||
CityStatsTable.pack();
|
||||
}
|
||||
|
||||
private void updateTileTable() {
|
||||
if(selectedTile == null) return;
|
||||
TileTable.clearChildren();
|
||||
|
||||
CityInfo City =game.civInfo.GetCurrentCity();
|
||||
FullStats stats = selectedTile.GetTileStats();
|
||||
TileTable.pad(20);
|
||||
TileTable.columnDefaults(0).padRight(10);
|
||||
|
||||
Label cityStatsHeader = new Label("Tile Stats",skin);
|
||||
cityStatsHeader.setFontScale(2);
|
||||
TileTable.add(cityStatsHeader).colspan(2).pad(10);
|
||||
TileTable.row();
|
||||
|
||||
TileTable.add(new Label(selectedTile.toString(),skin)).colspan(2);
|
||||
TileTable.row();
|
||||
|
||||
HashMap<String,String> TileStatsValues = new HashMap<String, String>();
|
||||
TileStatsValues.put("Production",stats.Production+"");
|
||||
TileStatsValues.put("Food",stats.Food+"");
|
||||
TileStatsValues.put("Gold",stats.Gold+"");
|
||||
TileStatsValues.put("Science",stats.Science+"");
|
||||
TileStatsValues.put("Culture",stats.Culture+"");
|
||||
|
||||
for(String key : TileStatsValues.keySet()){
|
||||
if(TileStatsValues.get(key).equals("0")) continue; // this tile gives nothing of this stat, so why even display it?
|
||||
TileTable.add(ImageGetter.getStatIcon(key)).align(Align.right);
|
||||
TileTable.add(new Label(TileStatsValues.get(key),skin)).align(Align.left);
|
||||
TileTable.row();
|
||||
}
|
||||
|
||||
TileTable.pack();
|
||||
|
||||
TileTable.setPosition(stage.getWidth()-10- TileTable.getWidth(), 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float delta) {
|
||||
for(TileGroup HG : tileGroups) {
|
||||
HG.update();
|
||||
}
|
||||
|
||||
super.render(delta);
|
||||
}
|
||||
|
||||
public static Pixmap getPixmapRoundedRectangle(int width, int height, int radius, int color) {
|
||||
Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
|
||||
pixmap.setBlending(Blending.None);
|
||||
pixmap.setColor(color);
|
||||
|
||||
pixmap.fillRectangle(0, radius, pixmap.getWidth(), pixmap.getHeight()-2*radius);
|
||||
pixmap.fillRectangle(radius, 0, pixmap.getWidth() - 2*radius, pixmap.getHeight());
|
||||
|
||||
pixmap.fillCircle(radius, radius, radius);
|
||||
pixmap.fillCircle(radius, pixmap.getHeight()-radius, radius);
|
||||
pixmap.fillCircle(pixmap.getWidth()-radius, radius, radius);
|
||||
pixmap.fillCircle(pixmap.getWidth()-radius, pixmap.getHeight()-radius, radius);
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
112
core/src/com/unciv/game/CivilopediaScreen.java
Normal file
112
core/src/com/unciv/game/CivilopediaScreen.java
Normal file
@ -0,0 +1,112 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Button;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.List;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.SplitPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Value;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.gamebasics.ICivilopedia;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class CivilopediaScreen extends CameraStageBaseScreen {
|
||||
public CivilopediaScreen(final UnCivGame game) {
|
||||
|
||||
super(game);
|
||||
Gdx.input.setInputProcessor(stage);
|
||||
Table buttonTable = new Table();
|
||||
buttonTable.pad(15);
|
||||
Table entryTable = new Table();
|
||||
SplitPane SP = new SplitPane(buttonTable, entryTable, true, skin);
|
||||
SP.setSplitAmount(0.2f);
|
||||
SP.setFillParent(true);
|
||||
|
||||
stage.addActor(SP);
|
||||
|
||||
final Label label = new Label("", skin);
|
||||
label.setWrap(true);
|
||||
|
||||
TextButton goToGameButton = new TextButton("Return \r\nto game",skin);
|
||||
goToGameButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setWorldScreen();
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
buttonTable.add(goToGameButton);
|
||||
|
||||
final LinkedHashMap<String, Collection<ICivilopedia>> map = new LinkedHashMap<String, Collection<ICivilopedia>>();
|
||||
|
||||
map.put("Basics", GameBasics.Helps.linqValues().as(ICivilopedia.class));
|
||||
map.put("Buildings", GameBasics.Buildings.linqValues().as(ICivilopedia.class));
|
||||
map.put("Resources", GameBasics.TileResources.linqValues().as(ICivilopedia.class));
|
||||
map.put("Terrains", GameBasics.Terrains.linqValues().as(ICivilopedia.class));
|
||||
map.put("Tile Improvements", GameBasics.TileImprovements.linqValues().as(ICivilopedia.class));
|
||||
|
||||
final List<ICivilopedia> nameList = new List<ICivilopedia>(skin);
|
||||
|
||||
final ClickListener namelistClickListener = new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
ICivilopedia building = nameList.getSelected();
|
||||
if (building == null) return;
|
||||
label.setText(building.GetDescription());
|
||||
super.clicked(event, x, y);
|
||||
}
|
||||
};
|
||||
nameList.addListener(namelistClickListener);
|
||||
|
||||
nameList.getStyle().fontColorSelected = Color.BLACK;
|
||||
nameList.getStyle().font.getData().setScale(1.5f);
|
||||
|
||||
final ArrayList<Button> buttons = new ArrayList<Button>();
|
||||
boolean first = true;
|
||||
for (final String str : map.keySet()) {
|
||||
final TextButton button = new TextButton(str, skin);
|
||||
button.getStyle().checkedFontColor = Color.BLACK;
|
||||
buttons.add(button);
|
||||
ClickListener listener = new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
Array<ICivilopedia> newArray = new Array<ICivilopedia>();
|
||||
for (ICivilopedia civ : map.get(str)) newArray.add(civ);
|
||||
nameList.setItems(newArray);
|
||||
nameList.setSelected(nameList.getItems().get(0));
|
||||
namelistClickListener.clicked(null, 0, 0); // fake-click the first item, so the text is displayed
|
||||
for (Button btn : buttons) btn.setChecked(false);
|
||||
button.setChecked(true);
|
||||
}
|
||||
};
|
||||
if (first) {// Fake-click the first button so that the user sees results immediately
|
||||
first = false;
|
||||
listener.clicked(null, 0, 0);
|
||||
}
|
||||
button.addListener(listener);
|
||||
button.getLabel().setFontScale(0.7f);
|
||||
buttonTable.add(button).width(button.getWidth()*0.7f);
|
||||
}
|
||||
|
||||
ScrollPane sp = new ScrollPane(nameList);
|
||||
sp.setupOverscroll(5, 1, 200);
|
||||
entryTable.add(sp).width(Value.percentWidth(0.25f, entryTable)).height(Value.percentHeight(0.7f, entryTable))
|
||||
.pad(Value.percentWidth(0.02f, entryTable));
|
||||
entryTable.add(label).colspan(4).width(Value.percentWidth(0.65f, entryTable)).height(Value.percentHeight(0.7f, entryTable))
|
||||
.pad(Value.percentWidth(0.02f, entryTable));
|
||||
|
||||
buttonTable.setWidth(stage.getWidth());
|
||||
}
|
||||
|
||||
}
|
||||
|
11
core/src/com/unciv/game/GameSettings.java
Normal file
11
core/src/com/unciv/game/GameSettings.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.unciv.game;
|
||||
|
||||
public class GameSettings{
|
||||
public float labelScale = 1.5f;
|
||||
float buttonScale = 0.9f;
|
||||
float tilesZoom = 1;
|
||||
float cityTilesX =0;
|
||||
float cityTilesY =0;
|
||||
float worldScrollX=0;
|
||||
float worldScrollY=0;
|
||||
}
|
86
core/src/com/unciv/game/HexMath.java
Normal file
86
core/src/com/unciv/game/HexMath.java
Normal file
@ -0,0 +1,86 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.unciv.models.LinqCollection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class HexMath
|
||||
{
|
||||
public static Vector2 GetVectorForAngle(float angle)
|
||||
{
|
||||
return new Vector2((float)Math.sin(angle), (float) Math.cos(angle));
|
||||
}
|
||||
|
||||
public static Vector2 GetVectorByClockHour(int hour)
|
||||
{
|
||||
return GetVectorForAngle((float) ((2 * Math.PI) * (hour / 12f)));
|
||||
}
|
||||
|
||||
// HexCoordinates are a (x,y) vector, where x is the vector getting us to the top-left hex (e.g. 10 o'clock)
|
||||
// and y is the vector getting us to the top-right hex (e.g. 2 o'clock)
|
||||
|
||||
// Each (1,1) vector effectively brings us up a layer.
|
||||
// For example, to get to the cell above me, I'll use a (1,1) vector.
|
||||
// To get to the cell below the cell to my bottom-right, I'll use a (-1,-2) vector.
|
||||
|
||||
public static Vector2 Hex2WorldCoords(Vector2 hexCoord)
|
||||
{
|
||||
// Distance between cells = 2* normal of triangle = 2* (sqrt(3)/2) = sqrt(3)
|
||||
Vector2 xVector = GetVectorByClockHour(10).scl((float) Math.sqrt(3));
|
||||
Vector2 yVector = GetVectorByClockHour(2).scl((float) Math.sqrt(3));
|
||||
return xVector.scl(hexCoord.x).add(yVector.scl(hexCoord.y));
|
||||
}
|
||||
|
||||
public static ArrayList<Vector2> GetAdjacentVectors(Vector2 origin){
|
||||
ArrayList<Vector2> vectors = new ArrayList<Vector2>();
|
||||
vectors.add(new Vector2(1, 0));
|
||||
vectors.add(new Vector2(1, 1));
|
||||
vectors.add(new Vector2(0, 1));
|
||||
vectors.add(new Vector2(-1, 0));
|
||||
vectors.add(new Vector2(-1, -1));
|
||||
vectors.add(new Vector2(0, -1));
|
||||
for(Vector2 vector : vectors) vector.add(origin);
|
||||
return vectors;
|
||||
}
|
||||
|
||||
public static LinqCollection<Vector2> GetVectorsInDistance(Vector2 origin, int distance){
|
||||
HashSet<Vector2> hexesToReturn = new HashSet<Vector2>();
|
||||
HashSet<Vector2> oldHexes;
|
||||
HashSet<Vector2> newHexes = new HashSet<Vector2>();
|
||||
hexesToReturn.add(origin);
|
||||
newHexes.add(origin);
|
||||
for (int i = 0; i < distance; i++) {
|
||||
oldHexes = newHexes;
|
||||
newHexes = new HashSet<Vector2>();
|
||||
for (Vector2 vector : oldHexes) {
|
||||
for (Vector2 adjacentVector : GetAdjacentVectors(vector)){
|
||||
if(hexesToReturn.contains(adjacentVector)) continue;
|
||||
hexesToReturn.add(adjacentVector);
|
||||
newHexes.add(adjacentVector);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new LinqCollection<Vector2>(hexesToReturn);
|
||||
}
|
||||
|
||||
public static int GetDistance(Vector2 origin, Vector2 destination){ // Yes, this is a dumb implementation. But I can't be arsed to think of a better one right now, other stuff to do.
|
||||
int distance = 0;
|
||||
while(true){
|
||||
if(GetVectorsInDistance(origin,distance).contains(destination)) return distance;
|
||||
distance++;
|
||||
}
|
||||
}
|
||||
|
||||
// public static boolean IsWithinDistance(Vector2 a, Vector2 b, int distance){
|
||||
// return GetVectorsInDistance(a,distance).contains(b);
|
||||
// Vector2 distanceVector = a.sub(b);
|
||||
// if(distanceVector.x<0) distanceVector = new Vector2(-distanceVector.x,-distanceVector.y);
|
||||
//
|
||||
// int distance = (int) Math.abs(distanceVector.x);
|
||||
// distanceVector = distanceVector.sub(distanceVector.x,distanceVector.x); // Zero X f distance, then we'll calculate Y
|
||||
// distance += Math.abs(distanceVector.y);
|
||||
// return distance;
|
||||
// }
|
||||
}
|
22
core/src/com/unciv/game/ImageGetter.java
Normal file
22
core/src/com/unciv/game/ImageGetter.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ImageGetter {
|
||||
static HashMap<String, TextureRegion> textureRegionByFileName = new HashMap<String, TextureRegion>();
|
||||
|
||||
public static Image getImageByFilename(String fileName) {
|
||||
if (!textureRegionByFileName.containsKey(fileName))
|
||||
textureRegionByFileName.put(fileName, new TextureRegion(new Texture(Gdx.files.internal(fileName))));
|
||||
return new Image(textureRegionByFileName.get(fileName));
|
||||
}
|
||||
|
||||
public static Image getStatIcon(String name) {
|
||||
return getImageByFilename("StatIcons/20x" + name + "5.png");
|
||||
}
|
||||
}
|
79
core/src/com/unciv/game/TileGroup.java
Normal file
79
core/src/com/unciv/game/TileGroup.java
Normal file
@ -0,0 +1,79 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Container;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.unciv.civinfo.TileInfo;
|
||||
|
||||
public class TileGroup extends Group {
|
||||
Image terrainImage;
|
||||
Image resourceImage;
|
||||
Image unitImage;
|
||||
Image improvementImage;
|
||||
Image populationImage;
|
||||
Image hexagon;
|
||||
|
||||
Container<TextButton> cityButton;
|
||||
TileInfo tileInfo;
|
||||
|
||||
TileGroup(TileInfo tileInfo){
|
||||
this.tileInfo = tileInfo;
|
||||
|
||||
String terrainFileName = "TerrainIcons/" + tileInfo.GetLastTerrain().Name + "_(Civ5).png";
|
||||
terrainImage = ImageGetter.getImageByFilename(terrainFileName);
|
||||
terrainImage.setSize(50,50);
|
||||
addActor(terrainImage);
|
||||
}
|
||||
|
||||
void addPopulationIcon(){
|
||||
populationImage = ImageGetter.getStatIcon("Population");
|
||||
populationImage.setAlign(Align.bottomRight);
|
||||
populationImage.setX(terrainImage.getWidth()-populationImage.getWidth());
|
||||
addActor(populationImage);
|
||||
}
|
||||
|
||||
void removePopulationIcon(){
|
||||
populationImage.remove();
|
||||
populationImage = null;
|
||||
}
|
||||
|
||||
|
||||
void update() {
|
||||
|
||||
if (tileInfo.HasViewableResource() && resourceImage == null) { // Need to add the resource image!
|
||||
String fileName = "ResourceIcons/" + tileInfo.Resource + "_(Civ5).png";
|
||||
Image image = ImageGetter.getImageByFilename(fileName);
|
||||
image.setScale(0.5f);
|
||||
image.setOrigin(Align.topRight);
|
||||
resourceImage = image;
|
||||
addActor(image);
|
||||
}
|
||||
|
||||
if (tileInfo.Unit != null && unitImage == null) {
|
||||
unitImage = ImageGetter.getImageByFilename("StatIcons/" + tileInfo.Unit.Name + "_(Civ5).png");
|
||||
addActor(unitImage);
|
||||
unitImage.setSize(20, 20);
|
||||
}
|
||||
|
||||
if (tileInfo.Unit == null && unitImage != null) {
|
||||
unitImage.remove();
|
||||
unitImage = null;
|
||||
}
|
||||
|
||||
|
||||
if (tileInfo.Improvement != null && improvementImage == null) {
|
||||
improvementImage = ImageGetter.getImageByFilename("ImprovementIcons/" + tileInfo.Improvement.replace(' ','_') + "_(Civ5).png");
|
||||
addActor(improvementImage);
|
||||
improvementImage.setSize(20, 20);
|
||||
improvementImage.moveBy(0, terrainImage.getHeight() - improvementImage.getHeight());
|
||||
}
|
||||
|
||||
if(populationImage!=null){
|
||||
if(tileInfo.IsWorked) populationImage.setColor(Color.WHITE);
|
||||
else populationImage.setColor(Color.GRAY);
|
||||
}
|
||||
}
|
||||
}
|
83
core/src/com/unciv/game/UnCivGame.java
Normal file
83
core/src/com/unciv/game/UnCivGame.java
Normal file
@ -0,0 +1,83 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.Game;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.unciv.civinfo.CivilizationInfo;
|
||||
import com.unciv.civinfo.Unit;
|
||||
import com.unciv.game.pickerscreens.GameSaver;
|
||||
import com.unciv.models.gamebasics.BasicHelp;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.gamebasics.Technology;
|
||||
import com.unciv.models.LinqHashMap;
|
||||
import com.unciv.models.gamebasics.TechColumn;
|
||||
import com.unciv.models.gamebasics.TileImprovement;
|
||||
|
||||
public class UnCivGame extends Game {
|
||||
|
||||
public static UnCivGame Current;
|
||||
public CivilizationInfo civInfo;
|
||||
public GameSettings settings = new GameSettings();
|
||||
|
||||
|
||||
public WorldScreen worldScreen;
|
||||
public void create() {
|
||||
SetupGameBasics();
|
||||
Current = this;
|
||||
if(GameSaver.GetSave("Autosave").exists()) GameSaver.LoadGame(this,"Autosave");
|
||||
else startNewGame();
|
||||
|
||||
worldScreen = new WorldScreen(this);
|
||||
setWorldScreen();
|
||||
}
|
||||
|
||||
public void startNewGame(){
|
||||
civInfo = new CivilizationInfo();
|
||||
civInfo.tileMap.get(Vector2.Zero).Unit = new Unit("Settler",2);
|
||||
|
||||
worldScreen = new WorldScreen(this);
|
||||
setWorldScreen();
|
||||
}
|
||||
|
||||
public void setWorldScreen(){
|
||||
setScreen(worldScreen);
|
||||
worldScreen.update();
|
||||
Gdx.input.setInputProcessor(worldScreen.stage);
|
||||
}
|
||||
|
||||
private <T> T GetFromJson(Class<T> tClass, String name){
|
||||
String jsonText = Gdx.files.internal("jsons/"+name+".json").readString();
|
||||
return new Json().fromJson(tClass,jsonText);
|
||||
}
|
||||
|
||||
private <T extends com.unciv.models.stats.NamedStats> LinqHashMap<String,T> CreateHashmap(Class<T> tClass, T[] items){
|
||||
LinqHashMap<String,T> hashMap = new LinqHashMap<String, T>();
|
||||
for(T item:items) hashMap.put(item.GetName(),item);
|
||||
return hashMap;
|
||||
}
|
||||
|
||||
private void SetupGameBasics() {
|
||||
GameBasics.Buildings = CreateHashmap(com.unciv.models.gamebasics.Building.class,GetFromJson(com.unciv.models.gamebasics.Building[].class,"Buildings"));
|
||||
GameBasics.Terrains = CreateHashmap(com.unciv.models.gamebasics.Terrain.class,GetFromJson(com.unciv.models.gamebasics.Terrain[].class,"Terrains"));
|
||||
GameBasics.TileResources = CreateHashmap(com.unciv.models.gamebasics.TileResource.class,GetFromJson(com.unciv.models.gamebasics.TileResource[].class,"TileResources"));
|
||||
GameBasics.TileImprovements = CreateHashmap(TileImprovement.class,GetFromJson(TileImprovement[].class,"TileImprovements"));
|
||||
GameBasics.Helps = CreateHashmap(BasicHelp.class,GetFromJson(BasicHelp[].class,"BasicHelp"));
|
||||
|
||||
TechColumn[] TechColumns = GetFromJson(TechColumn[].class, "Techs");
|
||||
GameBasics.Technologies = new LinqHashMap<String, Technology>();
|
||||
for(TechColumn techColumn : TechColumns){
|
||||
for(com.unciv.models.gamebasics.Technology tech : techColumn.Techs){
|
||||
tech.Cost = techColumn.TechCost;
|
||||
tech.Column = techColumn;
|
||||
GameBasics.Technologies.put(tech.Name,tech);
|
||||
}
|
||||
}
|
||||
for(com.unciv.models.gamebasics.Building building : GameBasics.Buildings.values()){
|
||||
if(building.RequiredTech == null) continue;
|
||||
TechColumn column = building.GetRequiredTech().Column;
|
||||
building.Cost = building.IsWonder ? column.WonderCost : column.BuildingCost;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
457
core/src/com/unciv/game/WorldScreen.java
Normal file
457
core/src/com/unciv/game/WorldScreen.java
Normal file
@ -0,0 +1,457 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Group;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.Predicate;
|
||||
import com.unciv.civinfo.CityInfo;
|
||||
import com.unciv.civinfo.TileInfo;
|
||||
import com.unciv.game.pickerscreens.GameSaver;
|
||||
import com.unciv.game.pickerscreens.ImprovementPickerScreen;
|
||||
import com.unciv.game.pickerscreens.TechPickerScreen;
|
||||
import com.unciv.models.LinqHashMap;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.gamebasics.TileImprovement;
|
||||
import com.unciv.models.stats.CivStats;
|
||||
import com.unciv.models.stats.FullStats;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class WorldScreen extends CameraStageBaseScreen {
|
||||
|
||||
TileInfo selectedTile = null;
|
||||
|
||||
TileInfo unitTile = null;
|
||||
ScrollPane scrollPane;
|
||||
|
||||
float buttonScale = game.settings.buttonScale;
|
||||
Table TileTable = new Table();
|
||||
Table CivTable = new Table();
|
||||
TextButton TechButton = new TextButton("",skin);
|
||||
public LinqHashMap<String,WorldTileGroup> tileGroups = new LinqHashMap<String, WorldTileGroup>();
|
||||
|
||||
Table OptionsTable = new Table();
|
||||
|
||||
|
||||
public WorldScreen(final UnCivGame game) {
|
||||
super(game);
|
||||
new Label("",skin).getStyle().font.getData().setScale(game.settings.labelScale);
|
||||
|
||||
addTiles();
|
||||
stage.addActor(TileTable);
|
||||
|
||||
Drawable tileTableBackground = new TextureRegionDrawable(new TextureRegion(new Texture("skin/tileTableBackground.png")))
|
||||
.tint(new Color(0x0040804f));
|
||||
tileTableBackground.setMinHeight(0);
|
||||
tileTableBackground.setMinWidth(0);
|
||||
TileTable.setBackground(tileTableBackground);
|
||||
OptionsTable.setBackground(tileTableBackground);
|
||||
|
||||
TextureRegionDrawable civBackground = new TextureRegionDrawable(new TextureRegion(new Texture("skin/civTableBackground.png")));
|
||||
// civBackground.tint(new Color(0x0040804f));
|
||||
CivTable.setBackground(civBackground.tint(new Color(0x0040804f)));
|
||||
|
||||
stage.addActor(CivTable);
|
||||
|
||||
stage.addActor(TechButton);
|
||||
|
||||
setCenterPosition(Vector2.Zero);
|
||||
|
||||
update();
|
||||
createNextTurnButton(); // needs civ table to be positioned
|
||||
addOptionsTable();
|
||||
}
|
||||
|
||||
public void update(){
|
||||
updateTechButton();
|
||||
updateTileTable();
|
||||
updateTiles();
|
||||
updateCivTable();
|
||||
}
|
||||
|
||||
void addOptionsTable(){
|
||||
OptionsTable.setVisible(false);
|
||||
|
||||
TextButton OpenCivilopediaButton = new TextButton("Civilopedia",skin);
|
||||
OpenCivilopediaButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setScreen(new CivilopediaScreen(game));
|
||||
OptionsTable.setVisible(false);
|
||||
}
|
||||
});
|
||||
OptionsTable.add(OpenCivilopediaButton).pad(10);
|
||||
OptionsTable.row();
|
||||
|
||||
TextButton StartNewGameButton = new TextButton("Start new game",skin);
|
||||
StartNewGameButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.startNewGame();
|
||||
}
|
||||
});
|
||||
OptionsTable.add(StartNewGameButton).pad(10);
|
||||
OptionsTable.row();
|
||||
|
||||
|
||||
|
||||
TextButton closeButton = new TextButton("Close",skin);
|
||||
closeButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
OptionsTable.setVisible(false);
|
||||
}
|
||||
});
|
||||
OptionsTable.add(closeButton).pad(10);
|
||||
OptionsTable.setPosition(stage.getWidth()/2-OptionsTable.getWidth()/2,
|
||||
stage.getHeight()/2-OptionsTable.getHeight()/2);
|
||||
stage.addActor(OptionsTable);
|
||||
}
|
||||
|
||||
private void updateTechButton() {
|
||||
TechButton.setVisible(game.civInfo.Cities.size()!=0);
|
||||
TechButton.clearListeners();
|
||||
TechButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setScreen(new TechPickerScreen(game));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
||||
if (game.civInfo.Tech.CurrentTechnology() == null) TechButton.setText("Choose a tech!");
|
||||
else TechButton.setText(game.civInfo.Tech.CurrentTechnology() + "\r\n"
|
||||
+ game.civInfo.TurnsToTech(game.civInfo.Tech.CurrentTechnology()) + " turns");
|
||||
|
||||
TechButton.setSize(TechButton.getPrefWidth(), TechButton.getPrefHeight());
|
||||
TechButton.setPosition(10, CivTable.getY() - TechButton.getHeight()-5);
|
||||
}
|
||||
|
||||
private void updateCivTable() {
|
||||
CivTable.clear();
|
||||
CivTable.row().pad(20);
|
||||
CivStats currentStats = game.civInfo.civStats;
|
||||
|
||||
TextButton CivilopediaButton = new TextButton("Menu",skin);
|
||||
CivilopediaButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
OptionsTable.setVisible(true);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
||||
CivilopediaButton.getLabel().setFontScale(buttonScale);
|
||||
CivTable.add(CivilopediaButton)
|
||||
.size(CivilopediaButton.getWidth() * buttonScale, CivilopediaButton.getHeight() * buttonScale);
|
||||
|
||||
CivTable.add(new Label("Turns: " + game.civInfo.turns+"/400", skin));
|
||||
|
||||
CivStats nextTurnStats = game.civInfo.GetStatsForNextTurn();
|
||||
|
||||
CivTable.add(new Label("Gold: " + currentStats.Gold + "(" +(nextTurnStats.Gold>0?"+":"") + nextTurnStats.Gold+")", skin));
|
||||
|
||||
CivTable.add(new Label("Science: +" + nextTurnStats.Science, skin));
|
||||
CivTable.add(new Label("Happiness: " + nextTurnStats.Happiness, skin));
|
||||
CivTable.add(new Label("Culture: " + currentStats.Culture + "(+" + nextTurnStats.Culture+")", skin));
|
||||
|
||||
CivTable.pack();
|
||||
|
||||
CivTable.setPosition(10, stage.getHeight() - 10 - CivTable.getHeight());
|
||||
CivTable.setWidth(stage.getWidth() - 20);
|
||||
|
||||
}
|
||||
|
||||
private void createNextTurnButton() {
|
||||
TextButton nextTurnButton = new TextButton("Next turn", skin);
|
||||
nextTurnButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
if (game.civInfo.Tech.CurrentTechnology() == null
|
||||
&& game.civInfo.Cities.size()!=0) {
|
||||
game.setScreen(new TechPickerScreen(game));
|
||||
dispose();
|
||||
return;
|
||||
}
|
||||
game.civInfo.NextTurn();
|
||||
GameSaver.SaveGame(game,"Autosave");
|
||||
update();
|
||||
}
|
||||
});
|
||||
nextTurnButton.setPosition(stage.getWidth() - nextTurnButton.getWidth() - 10,
|
||||
CivTable.getY() - nextTurnButton.getHeight() - 10);
|
||||
stage.addActor(nextTurnButton);
|
||||
}
|
||||
|
||||
|
||||
private void addTiles() {
|
||||
final Group allTiles = new Group();
|
||||
|
||||
float topX = 0;
|
||||
float topY = 0;
|
||||
float bottomX = 0;
|
||||
float bottomY = 0;
|
||||
|
||||
for (final TileInfo tileInfo : game.civInfo.tileMap.values()) {
|
||||
final WorldTileGroup group = new WorldTileGroup(tileInfo);
|
||||
|
||||
group.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
selectedTile = tileInfo;
|
||||
if(unitTile != null && group.tileInfo.Unit == null ) {
|
||||
int distance = HexMath.GetDistance(unitTile.Position, group.tileInfo.Position);
|
||||
if (distance <= unitTile.Unit.CurrentMovement) {
|
||||
unitTile.Unit.CurrentMovement -= distance;
|
||||
group.tileInfo.Unit = unitTile.Unit;
|
||||
unitTile.Unit = null;
|
||||
unitTile = null;
|
||||
selectedTile = group.tileInfo;
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Vector2 positionalVector = HexMath.Hex2WorldCoords(tileInfo.Position);
|
||||
int groupSize = 50;
|
||||
group.setPosition(stage.getWidth() / 2 + positionalVector.x * 0.8f * groupSize,
|
||||
stage.getHeight() / 2 + positionalVector.y * 0.8f * groupSize);
|
||||
group.setSize(groupSize, groupSize);
|
||||
tileGroups.put(tileInfo.Position.toString(), group);
|
||||
allTiles.addActor(group);
|
||||
topX = Math.max(topX, group.getX() + groupSize);
|
||||
topY = Math.max(topY, group.getY() + groupSize);
|
||||
bottomX = Math.min(bottomX, group.getX());
|
||||
bottomY = Math.min(bottomY, group.getY());
|
||||
}
|
||||
|
||||
for (TileGroup group : tileGroups.linqValues()) {
|
||||
group.moveBy(-bottomX, -bottomY);
|
||||
}
|
||||
|
||||
// allTiles.setPosition(-bottomX,-bottomY); // there are tiles "below the zero",
|
||||
// so we zero out the starting position of the whole board so they will be displayed as well
|
||||
allTiles.setSize(topX - bottomX, topY - bottomY);
|
||||
|
||||
|
||||
scrollPane = new ScrollPane(allTiles);
|
||||
scrollPane.setFillParent(true);
|
||||
scrollPane.setOrigin(stage.getWidth() / 2, stage.getHeight() / 2);
|
||||
scrollPane.setScale(game.settings.tilesZoom);
|
||||
scrollPane.setSize(stage.getWidth(), stage.getHeight());
|
||||
scrollPane.addListener(new ActorGestureListener() {
|
||||
public float lastScale = 1;
|
||||
float lastInitialDistance = 0;
|
||||
|
||||
@Override
|
||||
public void zoom(InputEvent event, float initialDistance, float distance) {
|
||||
if (lastInitialDistance != initialDistance) {
|
||||
lastInitialDistance = initialDistance;
|
||||
lastScale = scrollPane.getScaleX();
|
||||
}
|
||||
float scale = (float) Math.sqrt(distance / initialDistance) * lastScale;
|
||||
scrollPane.setScale(scale);
|
||||
game.settings.tilesZoom = scale;
|
||||
}
|
||||
|
||||
});
|
||||
stage.addActor(scrollPane);
|
||||
}
|
||||
|
||||
private void updateTileTable() {
|
||||
if(selectedTile == null) return;
|
||||
TileTable.clearChildren();
|
||||
FullStats stats = selectedTile.GetTileStats();
|
||||
TileTable.pad(20);
|
||||
TileTable.columnDefaults(0).padRight(10);
|
||||
|
||||
Label cityStatsHeader = new Label("Tile Stats",skin);
|
||||
cityStatsHeader.setFontScale(2);
|
||||
TileTable.add(cityStatsHeader).colspan(2).pad(10);
|
||||
TileTable.row();
|
||||
|
||||
TileTable.add(new Label(selectedTile.toString(),skin)).colspan(2);
|
||||
TileTable.row();
|
||||
|
||||
HashMap<String,String> TileStatsValues = new HashMap<String, String>();
|
||||
TileStatsValues.put("Production",stats.Production+"");
|
||||
TileStatsValues.put("Food",stats.Food+"");
|
||||
TileStatsValues.put("Gold",stats.Gold+"");
|
||||
TileStatsValues.put("Science",stats.Science+"");
|
||||
TileStatsValues.put("Culture",stats.Culture+"");
|
||||
|
||||
for(String key : TileStatsValues.keySet()){
|
||||
if(TileStatsValues.get(key).equals("0")) continue; // this tile gives nothing of this stat, so why even display it?
|
||||
TileTable.add(ImageGetter.getStatIcon(key)).align(Align.right);
|
||||
TileTable.add(new Label(TileStatsValues.get(key),skin)).align(Align.left);
|
||||
TileTable.row();
|
||||
}
|
||||
|
||||
if(selectedTile.Unit!=null){
|
||||
TextButton moveUnitButton = new TextButton("Move to", skin);
|
||||
if(unitTile == selectedTile) moveUnitButton = new TextButton("Stop movement",skin);
|
||||
moveUnitButton.getLabel().setFontScale(buttonScale);
|
||||
if(selectedTile.Unit.CurrentMovement == 0){
|
||||
moveUnitButton.setColor(Color.GRAY);
|
||||
moveUnitButton.setTouchable(Touchable.disabled);
|
||||
}
|
||||
moveUnitButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
if(unitTile!=null) {
|
||||
unitTile = null;
|
||||
update();
|
||||
return;
|
||||
}
|
||||
unitTile = selectedTile;
|
||||
|
||||
// Set all tiles transparent except those in unit range
|
||||
for(TileGroup TG : tileGroups.linqValues()) TG.setColor(0,0,0,0.3f);
|
||||
for(Vector2 vector : HexMath.GetVectorsInDistance(unitTile.Position, unitTile.Unit.CurrentMovement)){
|
||||
if(tileGroups.containsKey(vector.toString()))
|
||||
tileGroups.get(vector.toString()).setColor(Color.WHITE);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
});
|
||||
TileTable.add(moveUnitButton).colspan(2)
|
||||
.size(moveUnitButton.getWidth() * buttonScale, moveUnitButton.getHeight() * buttonScale);
|
||||
|
||||
if(selectedTile.Unit.Name.equals("Settler")){
|
||||
TextButton foundCityButton = new TextButton("Found City", skin);
|
||||
foundCityButton.getLabel().setFontScale(buttonScale);
|
||||
foundCityButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.civInfo.addCity(selectedTile.Position);
|
||||
selectedTile.Unit = null; // Remove settler!
|
||||
update();
|
||||
}
|
||||
});
|
||||
|
||||
if(HexMath.GetVectorsInDistance(selectedTile.Position,2).any(new Predicate<Vector2>() {
|
||||
@Override
|
||||
public boolean evaluate(Vector2 arg0) {
|
||||
return tileGroups.containsKey(arg0.toString()) &&
|
||||
tileGroups.get(arg0.toString()).tileInfo.IsCityCenter();
|
||||
}
|
||||
})){
|
||||
foundCityButton.setDisabled(true);
|
||||
foundCityButton.setColor(Color.GRAY);
|
||||
}
|
||||
|
||||
TileTable.row();
|
||||
TileTable.add(foundCityButton).colspan(2)
|
||||
.size(foundCityButton.getWidth() * buttonScale, foundCityButton.getHeight() * buttonScale);
|
||||
}
|
||||
|
||||
if(selectedTile.Unit.Name.equals("Worker")) {
|
||||
String improvementButtonText = selectedTile.ImprovementInProgress == null ?
|
||||
"Construct\r\nimprovement" : selectedTile.ImprovementInProgress+"\r\nin progress";
|
||||
TextButton improvementButton = new TextButton(improvementButtonText, skin);
|
||||
improvementButton.getLabel().setFontScale(buttonScale);
|
||||
improvementButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setScreen(new ImprovementPickerScreen(game, selectedTile));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
if(!GameBasics.TileImprovements.linqValues().any(new Predicate<TileImprovement>() {
|
||||
@Override
|
||||
public boolean evaluate(TileImprovement arg0) {
|
||||
return selectedTile.CanBuildImprovement(arg0);
|
||||
}
|
||||
})){
|
||||
improvementButton.setColor(Color.GRAY);
|
||||
improvementButton.setTouchable(Touchable.disabled);
|
||||
}
|
||||
|
||||
TileTable.row();
|
||||
TileTable.add(improvementButton).colspan(2)
|
||||
.size(improvementButton.getWidth() * buttonScale, improvementButton.getHeight() * buttonScale);
|
||||
}
|
||||
}
|
||||
|
||||
TileTable.pack();
|
||||
|
||||
// TileTable.setBackground(getTableBackground(TileTable.getWidth(),TileTable.getHeight()));
|
||||
|
||||
TileTable.setPosition(stage.getWidth()-10- TileTable.getWidth(), 10);
|
||||
}
|
||||
|
||||
private void updateTiles() {
|
||||
for (WorldTileGroup WG : tileGroups.linqValues()) WG.update(this);
|
||||
|
||||
|
||||
|
||||
if(unitTile!=null) return; // While we're in "unit move" mode, no tiles but the tiles the unit can move to will be "visible"
|
||||
|
||||
// YES A TRIPLE FOR, GOT PROBLEMS WITH THAT?
|
||||
// Seriously though, there is probably a more efficient way of doing this, probably?
|
||||
// The original implementation caused serious lag on android, so efficiency is key, here
|
||||
for (WorldTileGroup WG : tileGroups.linqValues()) WG.setIsViewable(false);
|
||||
HashSet<String> ViewableVectorStrings = new HashSet<String>();
|
||||
|
||||
// tiles adjacent to city tiles
|
||||
for(CityInfo city : game.civInfo.Cities)
|
||||
for(Vector2 tileLocation : city.CityTileLocations)
|
||||
for(Vector2 adjacentLocation : HexMath.GetAdjacentVectors(tileLocation))
|
||||
ViewableVectorStrings.add(adjacentLocation.toString());
|
||||
|
||||
// Tiles within 2 tiles of units
|
||||
for(TileInfo tile : game.civInfo.tileMap.values()
|
||||
.where(new Predicate<TileInfo>() {
|
||||
@Override
|
||||
public boolean evaluate(TileInfo arg0) {
|
||||
return arg0.Unit!=null;
|
||||
}
|
||||
}))
|
||||
for(Vector2 vector : HexMath.GetVectorsInDistance(tile.Position,2))
|
||||
ViewableVectorStrings.add(vector.toString());
|
||||
|
||||
for(String string : ViewableVectorStrings)
|
||||
if(tileGroups.containsKey(string))
|
||||
tileGroups.get(string).setIsViewable(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void setCenterPosition(final Vector2 vector){
|
||||
TileGroup TG = tileGroups.linqValues().first(new Predicate<WorldTileGroup>() {
|
||||
@Override
|
||||
public boolean evaluate(WorldTileGroup arg0) {
|
||||
return arg0.tileInfo.Position.equals(vector) ;
|
||||
}
|
||||
});
|
||||
float x = TG.getX()-stage.getWidth()/2;
|
||||
float y = TG.getY()-stage.getHeight()/2;
|
||||
scrollPane.layout();
|
||||
scrollPane.setScrollX(x);
|
||||
scrollPane.setScrollY(y);
|
||||
scrollPane.updateVisualScroll();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
79
core/src/com/unciv/game/WorldTileGroup.java
Normal file
79
core/src/com/unciv/game/WorldTileGroup.java
Normal file
@ -0,0 +1,79 @@
|
||||
package com.unciv.game;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Container;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.utils.Predicate;
|
||||
import com.unciv.civinfo.CityInfo;
|
||||
import com.unciv.civinfo.CivilizationInfo;
|
||||
import com.unciv.civinfo.TileInfo;
|
||||
|
||||
|
||||
|
||||
public class WorldTileGroup extends TileGroup {
|
||||
|
||||
WorldTileGroup(TileInfo tileInfo) {
|
||||
super(tileInfo);
|
||||
}
|
||||
|
||||
void setIsViewable(boolean isViewable) {
|
||||
if (isViewable) setColor(1, 1, 0, 1); // Only alpha really changes anything
|
||||
else setColor(0, 0, 0, 0.3f);
|
||||
}
|
||||
|
||||
|
||||
void update(WorldScreen worldScreen) {
|
||||
super.update();
|
||||
|
||||
if(tileInfo.IsWorked && populationImage==null) addPopulationIcon();
|
||||
if(!tileInfo.IsWorked && populationImage!=null) removePopulationIcon();
|
||||
|
||||
|
||||
if (tileInfo.GetCity() != null && hexagon == null) {
|
||||
hexagon = ImageGetter.getImageByFilename("TerrainIcons/Hexagon.png");
|
||||
float imageScale = terrainImage.getWidth() * 1.3f / hexagon.getWidth();
|
||||
hexagon.setScale(imageScale);
|
||||
hexagon.setPosition((getWidth() - hexagon.getWidth() * imageScale) / 2,
|
||||
(getHeight() - hexagon.getHeight() * imageScale) / 2);
|
||||
addActor(hexagon);
|
||||
hexagon.setZIndex(0);
|
||||
}
|
||||
|
||||
|
||||
final CityInfo city = tileInfo.GetCity();
|
||||
if (tileInfo.IsCityCenter()) {
|
||||
if (cityButton == null) {
|
||||
cityButton = new Container<TextButton>();
|
||||
cityButton.setActor(new TextButton("", worldScreen.skin));
|
||||
|
||||
cityButton.getActor().getLabel().setFontScale(0.7f);
|
||||
|
||||
final UnCivGame game = worldScreen.game;
|
||||
cityButton.getActor().addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.civInfo.CurrentCity = game.civInfo.Cities.indexOf(city);
|
||||
game.setScreen(new CityScreen(game));
|
||||
}
|
||||
});
|
||||
|
||||
addActor(cityButton);
|
||||
setZIndex(getParent().getChildren().size);
|
||||
}
|
||||
|
||||
String cityButtonText = city.Name+" ("+city.cityPopulation.Population+")"
|
||||
+ "\r\n" + city.cityBuildings.CurrentBuilding + " in "
|
||||
+ city.cityBuildings.TurnsToBuilding(city.cityBuildings.CurrentBuilding);
|
||||
TextButton button = cityButton.getActor();
|
||||
button.setText(cityButtonText);
|
||||
button.setSize(button.getPrefWidth(), button.getPrefHeight());
|
||||
|
||||
cityButton.setPosition((getWidth() - cityButton.getWidth()) / 2,
|
||||
getHeight() * 0.9f);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package com.unciv.game.pickerscreens;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.unciv.civinfo.CityBuildings;
|
||||
import com.unciv.game.CityScreen;
|
||||
import com.unciv.game.UnCivGame;
|
||||
import com.unciv.models.gamebasics.Building;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
|
||||
public class BuildingPickerScreen extends PickerScreen {
|
||||
Building selectedBuilding;
|
||||
|
||||
public BuildingPickerScreen(final UnCivGame game) {
|
||||
super(game);
|
||||
|
||||
closeButton.clearListeners(); // Don't go back to the world screen, unlike the other picker screens!
|
||||
closeButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setScreen(new CityScreen(game));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
||||
rightSideButton.setText("Pick building");
|
||||
rightSideButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.civInfo.GetCurrentCity().cityBuildings.CurrentBuilding = selectedBuilding.Name;
|
||||
game.setScreen(new CityScreen(game));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
rightSideButton.setTouchable(Touchable.disabled);
|
||||
rightSideButton.setColor(Color.GRAY);
|
||||
|
||||
CityBuildings cityBuildings = game.civInfo.GetCurrentCity().cityBuildings;
|
||||
for(final Building building : GameBasics.Buildings.values()) {
|
||||
if(!cityBuildings.CanBuild(building)) continue;
|
||||
TextButton TB = new TextButton(building.Name+"\r\n"+cityBuildings.TurnsToBuilding(building.Name)+" turns", skin);
|
||||
TB.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
selectedBuilding = building;
|
||||
rightSideButton.setTouchable(Touchable.enabled);
|
||||
rightSideButton.setText("Build "+building.Name);
|
||||
rightSideButton.setColor(Color.WHITE);
|
||||
descriptionLabel.setText(building.GetDescription());
|
||||
}
|
||||
});
|
||||
topTable.add(TB).pad(10);
|
||||
topTable.row();
|
||||
}
|
||||
}
|
||||
}
|
23
core/src/com/unciv/game/pickerscreens/GameSaver.java
Normal file
23
core/src/com/unciv/game/pickerscreens/GameSaver.java
Normal file
@ -0,0 +1,23 @@
|
||||
package com.unciv.game.pickerscreens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.unciv.civinfo.CivilizationInfo;
|
||||
import com.unciv.game.UnCivGame;
|
||||
|
||||
public class GameSaver {
|
||||
public static final String saveFilesFolder = "SaveFiles";
|
||||
|
||||
public static FileHandle GetSave(String GameName) {
|
||||
return Gdx.files.local(saveFilesFolder + "/" + GameName);
|
||||
}
|
||||
|
||||
public static void SaveGame(UnCivGame game, String GameName) {
|
||||
GetSave(GameName).writeString(new Json().toJson(game.civInfo), false);
|
||||
}
|
||||
|
||||
public static void LoadGame(UnCivGame game, String GameName) {
|
||||
game.civInfo = new Json().fromJson(CivilizationInfo.class, GetSave(GameName).readString());
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.unciv.game.pickerscreens;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.SplitPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.unciv.game.CameraStageBaseScreen;
|
||||
import com.unciv.game.UnCivGame;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.gamebasics.TileImprovement;
|
||||
|
||||
public class ImprovementPickerScreen extends CameraStageBaseScreen {
|
||||
TileImprovement SelectedImprovement;
|
||||
|
||||
public ImprovementPickerScreen(final UnCivGame game, final com.unciv.civinfo.TileInfo tileInfo) {
|
||||
super(game);
|
||||
|
||||
Table buttonTable = new Table();
|
||||
TextButton closeButton =new TextButton("Close", skin);
|
||||
closeButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setScreen(new com.unciv.game.CityScreen(game));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
// closeButton.getLabel().setFontScale(0.7f);
|
||||
buttonTable.add(closeButton).width(stage.getWidth()/4);
|
||||
|
||||
final Label improvementDescription = new Label("",skin);
|
||||
buttonTable.add(improvementDescription).width(stage.getWidth()/2).pad(5);
|
||||
improvementDescription.setFontScale(game.settings.labelScale);
|
||||
|
||||
final TextButton pickImprovementButton = new TextButton("Pick improvement",skin);
|
||||
pickImprovementButton.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
tileInfo.StartWorkingOnImprovement(SelectedImprovement);
|
||||
game.setWorldScreen();
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
// pickImprovementButton.getLabel().setFontScale(0.7f);
|
||||
pickImprovementButton.setTouchable(Touchable.disabled);
|
||||
pickImprovementButton.setColor(Color.GRAY);
|
||||
buttonTable.add(pickImprovementButton).width(stage.getWidth()/4);
|
||||
|
||||
Table buildingsTable = new Table();
|
||||
for(final TileImprovement improvement : GameBasics.TileImprovements.values()) {
|
||||
if(!tileInfo.CanBuildImprovement(improvement)) continue;
|
||||
TextButton TB = new TextButton(improvement.Name+"\r\n"+improvement.TurnsToBuild+" turns", skin);
|
||||
TB.addListener(new ClickListener(){
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
SelectedImprovement = improvement;
|
||||
pickImprovementButton.setTouchable(Touchable.enabled);
|
||||
pickImprovementButton.setText("Construct "+improvement.Name);
|
||||
pickImprovementButton.setColor(Color.WHITE);
|
||||
improvementDescription.setText(improvement.GetDescription());
|
||||
}
|
||||
});
|
||||
buildingsTable.add(TB).pad(10);
|
||||
buildingsTable.row();
|
||||
}
|
||||
ScrollPane scrollPane = new ScrollPane(buildingsTable);
|
||||
scrollPane.setSize(stage.getWidth(),stage.getHeight()*0.9f);
|
||||
|
||||
|
||||
SplitPane splitPane = new SplitPane(scrollPane, buttonTable, true, skin);
|
||||
splitPane.setSplitAmount(0.9f);
|
||||
splitPane.setFillParent(true);
|
||||
stage.addActor(splitPane);
|
||||
}
|
||||
}
|
60
core/src/com/unciv/game/pickerscreens/PickerScreen.java
Normal file
60
core/src/com/unciv/game/pickerscreens/PickerScreen.java
Normal file
@ -0,0 +1,60 @@
|
||||
package com.unciv.game.pickerscreens;
|
||||
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.SplitPane;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.unciv.game.CameraStageBaseScreen;
|
||||
import com.unciv.game.UnCivGame;
|
||||
|
||||
public class PickerScreen extends CameraStageBaseScreen {
|
||||
|
||||
TextButton closeButton;
|
||||
Label descriptionLabel;
|
||||
TextButton rightSideButton;
|
||||
float screenSplit = 0.85f;
|
||||
Table topTable;
|
||||
SplitPane splitPane;
|
||||
|
||||
|
||||
public PickerScreen(final UnCivGame game) {
|
||||
super(game);
|
||||
|
||||
Table buttonTable = new Table();
|
||||
|
||||
closeButton = new TextButton("Close", skin);
|
||||
closeButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
game.setWorldScreen();
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
buttonTable.add(closeButton).width(stage.getWidth() / 4);
|
||||
|
||||
descriptionLabel = new Label("", skin);
|
||||
descriptionLabel.setWrap(true);
|
||||
descriptionLabel.setFontScale(game.settings.labelScale);
|
||||
descriptionLabel.setWidth(stage.getWidth() / 2);
|
||||
buttonTable.add(descriptionLabel).pad(5).width(stage.getWidth() / 2);
|
||||
|
||||
rightSideButton = new TextButton("", skin);
|
||||
buttonTable.add(rightSideButton).width(stage.getWidth() / 4);
|
||||
buttonTable.setHeight(stage.getHeight()*(1-screenSplit));
|
||||
buttonTable.align(Align.center);
|
||||
|
||||
topTable = new Table();
|
||||
ScrollPane scrollPane = new ScrollPane(topTable);
|
||||
|
||||
scrollPane.setSize(stage.getWidth(), stage.getHeight() * screenSplit);
|
||||
|
||||
splitPane = new SplitPane(scrollPane, buttonTable, true, skin);
|
||||
splitPane.setSplitAmount(screenSplit);
|
||||
splitPane.setFillParent(true);
|
||||
stage.addActor(splitPane);
|
||||
}
|
||||
}
|
139
core/src/com/unciv/game/pickerscreens/TechPickerScreen.java
Normal file
139
core/src/com/unciv/game/pickerscreens/TechPickerScreen.java
Normal file
@ -0,0 +1,139 @@
|
||||
package com.unciv.game.pickerscreens;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.unciv.game.UnCivGame;
|
||||
import com.unciv.models.gamebasics.GameBasics;
|
||||
import com.unciv.models.gamebasics.Technology;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Stack;
|
||||
|
||||
public class TechPickerScreen extends PickerScreen {
|
||||
|
||||
HashMap<String, TextButton> techNameToButton = new HashMap<String, TextButton>();
|
||||
Technology SelectedTech;
|
||||
com.unciv.civinfo.CivilizationTech civTech = game.civInfo.Tech;
|
||||
ArrayList<String> TechsToResearch = new ArrayList<String>(civTech.TechsToResearch);
|
||||
|
||||
public void SetButtonsInfo() {
|
||||
|
||||
for (String techName : techNameToButton.keySet()) {
|
||||
TextButton TB = techNameToButton.get(techName);
|
||||
TB.getStyle().checkedFontColor = Color.BLACK;
|
||||
if (civTech.IsResearched(techName)) TB.setColor(Color.GREEN);
|
||||
else if (TechsToResearch.contains(techName)) TB.setColor(Color.BLUE);
|
||||
else if (civTech.CanBeResearched(techName)) TB.setColor(Color.WHITE);
|
||||
else TB.setColor(Color.GRAY);
|
||||
|
||||
TB.setChecked(false);
|
||||
TB.setText(techName);
|
||||
|
||||
if (SelectedTech != null) {
|
||||
Technology thisTech = GameBasics.Technologies.get(techName);
|
||||
if (techName.equals(SelectedTech.Name)) {
|
||||
TB.setChecked(true);
|
||||
TB.setColor(TB.getColor().lerp(Color.LIGHT_GRAY, 0.5f));
|
||||
}
|
||||
|
||||
if (thisTech.Prerequisites.contains(SelectedTech.Name)) TB.setText("*" + techName);
|
||||
else if (SelectedTech.Prerequisites.contains(techName)) TB.setText(techName + "*");
|
||||
}
|
||||
if (TechsToResearch.contains(techName)) {
|
||||
TB.setText(TB.getText() + " (" + TechsToResearch.indexOf(techName) + ")");
|
||||
}
|
||||
TB.setText(TB.getText() + "\r\n" + game.civInfo.TurnsToTech(techName) + " turns");
|
||||
}
|
||||
}
|
||||
|
||||
public void selectTechnology(Technology tech) {
|
||||
SelectedTech = tech;
|
||||
descriptionLabel.setText(tech.Description);
|
||||
|
||||
if (civTech.IsResearched(tech.Name)) {
|
||||
rightSideButton.setText("Research");
|
||||
rightSideButton.setTouchable(Touchable.disabled);
|
||||
rightSideButton.setColor(Color.GRAY);
|
||||
SetButtonsInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
rightSideButton.setTouchable(Touchable.enabled);
|
||||
rightSideButton.setColor(Color.WHITE);
|
||||
|
||||
if (civTech.CanBeResearched(tech.Name)) {
|
||||
TechsToResearch.clear();
|
||||
TechsToResearch.add(tech.Name);
|
||||
} else {
|
||||
Stack<String> Prerequisites = new Stack<String>();
|
||||
ArrayDeque<String> CheckPrerequisites = new ArrayDeque<String>();
|
||||
CheckPrerequisites.add(tech.Name);
|
||||
while (!CheckPrerequisites.isEmpty()) {
|
||||
String techNameToCheck = CheckPrerequisites.pop();
|
||||
if (civTech.IsResearched(techNameToCheck))
|
||||
continue; //no need to add or check prerequisites
|
||||
Technology techToCheck = GameBasics.Technologies.get(techNameToCheck);
|
||||
for (String str : techToCheck.Prerequisites)
|
||||
if (!CheckPrerequisites.contains(str)) CheckPrerequisites.add(str);
|
||||
Prerequisites.add(techNameToCheck);
|
||||
}
|
||||
TechsToResearch.clear();
|
||||
while (!Prerequisites.isEmpty()) TechsToResearch.add(Prerequisites.pop());
|
||||
}
|
||||
|
||||
rightSideButton.setText("Research \r\n" + TechsToResearch.get(0));
|
||||
SetButtonsInfo();
|
||||
}
|
||||
|
||||
public TechPickerScreen(final UnCivGame game) {
|
||||
super(game);
|
||||
|
||||
Technology[][] techMatrix = new Technology[10][5]; // Divided into columns, then rows
|
||||
for (int i = 0; i < techMatrix.length; i++) {
|
||||
techMatrix[i] = new Technology[10];
|
||||
}
|
||||
|
||||
for (Technology technology : GameBasics.Technologies.linqValues()) {
|
||||
techMatrix[technology.Column.ColumnNumber][technology.Row - 1] = technology;
|
||||
}
|
||||
|
||||
// Table topTable = new Table();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
topTable.row().pad(5);
|
||||
|
||||
for (int j = 0; j < 6; j++) {
|
||||
final Technology tech = techMatrix[j][i];
|
||||
if (tech == null) topTable.add(); // empty cell
|
||||
else {
|
||||
final TextButton TB = new TextButton("", skin);
|
||||
techNameToButton.put(tech.Name, TB);
|
||||
TB.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
selectTechnology(tech);
|
||||
}
|
||||
});
|
||||
topTable.add(TB);
|
||||
}
|
||||
}
|
||||
SetButtonsInfo();
|
||||
}
|
||||
|
||||
rightSideButton.setText("Research");
|
||||
rightSideButton.setTouchable(Touchable.disabled);
|
||||
rightSideButton.setColor(Color.GRAY);
|
||||
rightSideButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
civTech.TechsToResearch = TechsToResearch;
|
||||
game.setWorldScreen();
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
62
core/src/com/unciv/models/LinqCollection.java
Normal file
62
core/src/com/unciv/models/LinqCollection.java
Normal file
@ -0,0 +1,62 @@
|
||||
package com.unciv.models;
|
||||
|
||||
import com.badlogic.gdx.utils.Predicate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Created by LENOVO on 10/20/2017.
|
||||
*/
|
||||
|
||||
public class LinqCollection <T> extends ArrayList<T> {
|
||||
public LinqCollection() {
|
||||
}
|
||||
|
||||
public LinqCollection(Collection<? extends T> objects) {
|
||||
this.addAll(objects);
|
||||
}
|
||||
|
||||
|
||||
public LinqCollection<T> where(Predicate<T> p) {
|
||||
LinqCollection<T> newCollection = new LinqCollection<T>();
|
||||
for (T t : this) if (p.evaluate(t)) newCollection.add(t);
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
public T first(Predicate<T> p) {
|
||||
for (T t : this) if (p.evaluate(t)) return t;
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean any(Predicate<T> p){ return first(p) != null;}
|
||||
|
||||
public int count(Predicate<T> p) {
|
||||
return where(p).size();
|
||||
}
|
||||
|
||||
public <T2> LinqCollection<T2> select(Func<T, T2> selector) {
|
||||
LinqCollection<T2> newCollection = new LinqCollection<T2>();
|
||||
for (T t : this) newCollection.add(selector.GetBy(t));
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
public T getRandom(){
|
||||
if(size()==0) return null;
|
||||
return get((int) (Math.random() * (size() - 1)));
|
||||
}
|
||||
|
||||
public interface Func<T1, T2> {
|
||||
public T2 GetBy(T1 arg0);
|
||||
}
|
||||
|
||||
public <T2> LinqCollection<T2> as(Class<T2> t2Class){
|
||||
LinqCollection<T2> newCollection = new LinqCollection<T2>();
|
||||
for (T t:this) newCollection.add((T2)t);
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
9
core/src/com/unciv/models/LinqHashMap.java
Normal file
9
core/src/com/unciv/models/LinqHashMap.java
Normal file
@ -0,0 +1,9 @@
|
||||
package com.unciv.models;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class LinqHashMap <K,V> extends LinkedHashMap<K,V> {
|
||||
public LinqCollection<V> linqValues() {
|
||||
return new LinqCollection<V>(super.values());
|
||||
}
|
||||
}
|
12
core/src/com/unciv/models/gamebasics/BasicHelp.java
Normal file
12
core/src/com/unciv/models/gamebasics/BasicHelp.java
Normal file
@ -0,0 +1,12 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import com.unciv.models.stats.NamedStats;
|
||||
|
||||
public class BasicHelp extends NamedStats implements ICivilopedia {
|
||||
public String Description;
|
||||
|
||||
@Override
|
||||
public String GetDescription() {
|
||||
return Description;
|
||||
}
|
||||
}
|
35
core/src/com/unciv/models/gamebasics/Building.java
Normal file
35
core/src/com/unciv/models/gamebasics/Building.java
Normal file
@ -0,0 +1,35 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import com.unciv.models.stats.NamedStats;
|
||||
|
||||
public class Building extends NamedStats implements ICivilopedia {
|
||||
public String Description;
|
||||
public String RequiredTech;
|
||||
public Technology GetRequiredTech(){return GameBasics.Technologies.get(RequiredTech);}
|
||||
public int Cost;
|
||||
public int Maintainance = 0;
|
||||
public com.unciv.models.stats.FullStats PercentStatBonus = new com.unciv.models.stats.FullStats();
|
||||
//public Func<CityInfo,FullStats> GetFlatBonusStats;
|
||||
public boolean IsWonder = false;
|
||||
public boolean ResourceRequired = false;
|
||||
public String RequiredBuilding;
|
||||
public String RequiredBuildingInAllCities;
|
||||
|
||||
// Uniques
|
||||
public String ProvidesFreeBuilding;
|
||||
public int FreeTechs;
|
||||
|
||||
|
||||
/** The bonus stats that a resource gets when this building is built */
|
||||
public com.unciv.models.stats.FullStats ResourceBonusStats;
|
||||
|
||||
public String GetDescription() {
|
||||
com.unciv.models.stats.FullStats stats = new com.unciv.models.stats.FullStats(this);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if(IsWonder) stringBuilder.append("Wonder\r\n");
|
||||
stringBuilder.append(Description + "\r\n" + stats);
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
12
core/src/com/unciv/models/gamebasics/GameBasics.java
Normal file
12
core/src/com/unciv/models/gamebasics/GameBasics.java
Normal file
@ -0,0 +1,12 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import com.unciv.models.LinqHashMap;
|
||||
|
||||
public class GameBasics{
|
||||
public static LinqHashMap<String,Building> Buildings;
|
||||
public static LinqHashMap<String,Terrain> Terrains;
|
||||
public static LinqHashMap<String,TileResource> TileResources;
|
||||
public static LinqHashMap<String,TileImprovement> TileImprovements;
|
||||
public static LinqHashMap<String, Technology> Technologies;
|
||||
public static LinqHashMap<String, BasicHelp> Helps;
|
||||
}
|
9
core/src/com/unciv/models/gamebasics/ICivilopedia.java
Normal file
9
core/src/com/unciv/models/gamebasics/ICivilopedia.java
Normal file
@ -0,0 +1,9 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
/**
|
||||
* Created by LENOVO on 10/18/2017.
|
||||
*/
|
||||
|
||||
public interface ICivilopedia {
|
||||
public String GetDescription();
|
||||
}
|
14
core/src/com/unciv/models/gamebasics/StringUtils.java
Normal file
14
core/src/com/unciv/models/gamebasics/StringUtils.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class StringUtils {
|
||||
public static String join(String delimiter, Collection<String> collection) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String str : collection) {
|
||||
if (stringBuilder.length() != 0) stringBuilder.append(delimiter);
|
||||
stringBuilder.append(str);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
13
core/src/com/unciv/models/gamebasics/TechColumn.java
Normal file
13
core/src/com/unciv/models/gamebasics/TechColumn.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TechColumn
|
||||
{
|
||||
public int ColumnNumber;
|
||||
public GameBasics gameBasics;
|
||||
public ArrayList<Technology> Techs = new ArrayList<Technology>();
|
||||
public int TechCost;
|
||||
public int BuildingCost;
|
||||
public int WonderCost;
|
||||
}
|
15
core/src/com/unciv/models/gamebasics/Technology.java
Normal file
15
core/src/com/unciv/models/gamebasics/Technology.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Technology
|
||||
{
|
||||
public String Name;
|
||||
|
||||
public String Description;
|
||||
public int Cost;
|
||||
public ArrayList<String> Prerequisites = new ArrayList<String>();
|
||||
|
||||
public TechColumn Column; // The column that this tech is in the tech tree
|
||||
public int Row;
|
||||
}
|
55
core/src/com/unciv/models/gamebasics/Terrain.java
Normal file
55
core/src/com/unciv/models/gamebasics/Terrain.java
Normal file
@ -0,0 +1,55 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import com.unciv.models.stats.FullStats;
|
||||
import com.unciv.models.stats.NamedStats;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class Terrain extends NamedStats implements ICivilopedia {
|
||||
public String Type; // BaseTerrain or TerrainFeature
|
||||
|
||||
/// <summary>
|
||||
/// For base terrain - comma-delimited 256 RGB values, e.g. "116,88,62"
|
||||
/// </summary>
|
||||
public String RGB;
|
||||
//
|
||||
//public Color Color
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// var rgbStringValues = RGB.Split(',');
|
||||
// var rgbs = rgbStringValues.Select(x => int.Parse(x)).ToArray();
|
||||
// return Extensions.ColorFrom256RGB(rgbs[0], rgbs[1], rgbs[2]);
|
||||
// }
|
||||
// }
|
||||
|
||||
public boolean OverrideStats = false;
|
||||
|
||||
/// <summary>
|
||||
/// If true, other terrain layers can come over this one. For mountains, lakes etc. this is false
|
||||
/// </summary>
|
||||
public boolean CanHaveOverlay = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true, nothing can be built here - not even resource improvements
|
||||
/// </summary>
|
||||
public boolean Unbuildable = false;
|
||||
|
||||
/// <summary>
|
||||
/// For terrain features
|
||||
/// </summary>
|
||||
public Collection<String> OccursOn;
|
||||
|
||||
/// <summary>
|
||||
/// For terrain features - which technology alllows removal of this feature
|
||||
/// </summary>
|
||||
public String RemovalTech;
|
||||
|
||||
@Override
|
||||
public String GetDescription() {
|
||||
return ""+new FullStats(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
41
core/src/com/unciv/models/gamebasics/TileImprovement.java
Normal file
41
core/src/com/unciv/models/gamebasics/TileImprovement.java
Normal file
@ -0,0 +1,41 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import com.unciv.models.stats.FullStats;
|
||||
import com.unciv.models.stats.NamedStats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class TileImprovement extends NamedStats implements ICivilopedia {
|
||||
public Collection<String> TerrainsCanBeBuiltOn = new ArrayList<String>();
|
||||
public String TechRequired;
|
||||
|
||||
public String ImprovingTech;
|
||||
public FullStats ImprovingTechStats;
|
||||
|
||||
public int TurnsToBuild;
|
||||
|
||||
@Override
|
||||
public String GetDescription() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(new FullStats(this)+"\r\n");
|
||||
if(!TerrainsCanBeBuiltOn.isEmpty()) stringBuilder.append("Can be built on " + com.unciv.models.gamebasics.StringUtils.join(", ", TerrainsCanBeBuiltOn));
|
||||
|
||||
HashMap<String,ArrayList<String>> statsToResourceNames = new HashMap<String, ArrayList<String>>();
|
||||
for(com.unciv.models.gamebasics.TileResource tr : GameBasics.TileResources.values()){
|
||||
if(!tr.Improvement.equals(Name)) continue;
|
||||
String statsString = tr.ImprovementStats.toString();
|
||||
if(!statsToResourceNames.containsKey(statsString))
|
||||
statsToResourceNames.put(statsString,new ArrayList<String>());
|
||||
statsToResourceNames.get(statsString).add(tr.Name);
|
||||
}
|
||||
for(String statsString : statsToResourceNames.keySet()){
|
||||
stringBuilder.append("\r\n"+statsString+" for "+ com.unciv.models.gamebasics.StringUtils.join(", ",statsToResourceNames.get(statsString)));
|
||||
}
|
||||
|
||||
if(TechRequired!=null) stringBuilder.append("\r\nTech required: "+TechRequired);
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
32
core/src/com/unciv/models/gamebasics/TileResource.java
Normal file
32
core/src/com/unciv/models/gamebasics/TileResource.java
Normal file
@ -0,0 +1,32 @@
|
||||
package com.unciv.models.gamebasics;
|
||||
|
||||
import com.unciv.models.stats.NamedStats;
|
||||
import com.unciv.models.stats.FullStats;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class TileResource extends NamedStats implements ICivilopedia {
|
||||
public String ResourceType;
|
||||
public Collection<String> TerrainsCanBeFoundOn;
|
||||
public String Improvement;
|
||||
public FullStats ImprovementStats;
|
||||
|
||||
/// <summary>
|
||||
/// The building that improves this resource, if any. E.G.: Granary for wheat, Stable for cattle.
|
||||
/// </summary>
|
||||
public String Building;
|
||||
public com.unciv.models.gamebasics.Building GetBuilding(){return Building==null ? null : GameBasics.Buildings.get(Building);}
|
||||
|
||||
public String RevealedBy;
|
||||
|
||||
@Override
|
||||
public String GetDescription() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(new FullStats(this)+"\r\n");
|
||||
stringBuilder.append("Can be found on " + com.unciv.models.gamebasics.StringUtils.join(", ",TerrainsCanBeFoundOn));
|
||||
stringBuilder.append("\r\n\r\nImproved by "+Improvement+"\r\n");
|
||||
stringBuilder.append("\r\nBonus stats for improvement: "+ImprovementStats+"\r\n");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
15
core/src/com/unciv/models/stats/CivStats.java
Normal file
15
core/src/com/unciv/models/stats/CivStats.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.unciv.models.stats;
|
||||
|
||||
public class CivStats {
|
||||
public int Gold = 0;
|
||||
public int Science = 0;
|
||||
public int Culture = 0;
|
||||
public int Happiness = 0;
|
||||
|
||||
public void add(CivStats other) {
|
||||
Gold += other.Gold;
|
||||
Science += other.Science;
|
||||
Happiness += other.Happiness;
|
||||
Culture += other.Culture;
|
||||
}
|
||||
}
|
41
core/src/com/unciv/models/stats/FullStats.java
Normal file
41
core/src/com/unciv/models/stats/FullStats.java
Normal file
@ -0,0 +1,41 @@
|
||||
package com.unciv.models.stats;
|
||||
|
||||
public class FullStats extends CivStats // also used for hex stats, since it's basically the same
|
||||
{
|
||||
public int Production = 0;
|
||||
public int Food = 0;
|
||||
|
||||
public FullStats() {
|
||||
}
|
||||
|
||||
public FullStats(FullStats other){
|
||||
add(other);
|
||||
}
|
||||
|
||||
public void add(FullStats other){
|
||||
Gold+=other.Gold;
|
||||
Science+=other.Science;
|
||||
Happiness+=other.Happiness;
|
||||
Culture+=other.Culture;
|
||||
Food+=other.Food;
|
||||
Production+=other.Production;
|
||||
}
|
||||
|
||||
public String display(int value, String name){
|
||||
return ", " + (value>0 ? "+" : "") + value + " "+name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder valuableParts = new StringBuilder();
|
||||
if (Production != 0) valuableParts.append(display(Production,"Production"));
|
||||
if (Food != 0) valuableParts.append(display(Food,"Food"));
|
||||
if (Gold != 0) valuableParts.append(display(Gold,"Gold"));
|
||||
if (Science != 0) valuableParts.append(display(Science,"Science"));
|
||||
if (Happiness != 0) valuableParts.append(display(Happiness,"Happpiness"));
|
||||
if (Culture != 0) valuableParts.append(display(Culture,"Culture"));
|
||||
if (valuableParts.length() == 0) return "";
|
||||
valuableParts.delete(0,1);
|
||||
return valuableParts.toString();
|
||||
}
|
||||
|
||||
}
|
13
core/src/com/unciv/models/stats/NamedStats.java
Normal file
13
core/src/com/unciv/models/stats/NamedStats.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.unciv.models.stats;
|
||||
|
||||
public class NamedStats extends FullStats {
|
||||
public String Name;
|
||||
|
||||
public String GetName() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Name;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user