From ede3a92c435d39d8b97721e4fb458fc6a15f53e1 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Mon, 11 Dec 2017 18:21:15 +0200 Subject: [PATCH] Finished techs and buildings! Added Science victory conditions and screen! --- android/assets/jsons/Buildings.json | 94 +++++++++- android/assets/jsons/Techs.json | 163 +++++++++++++++++- core/src/com/unciv/civinfo/CityBuildings.java | 51 ++++-- core/src/com/unciv/civinfo/CityInfo.java | 33 ++-- .../com/unciv/civinfo/CivilizationInfo.java | 20 +-- core/src/com/unciv/civinfo/TileMap.java | 2 +- core/src/com/unciv/game/CityScreen.java | 44 ++++- .../src/com/unciv/game/CivilopediaScreen.java | 2 +- .../com/unciv/game/ScienceVictoryScreen.java | 41 +++++ core/src/com/unciv/game/TileGroup.java | 16 +- core/src/com/unciv/game/UnCivGame.java | 6 +- core/src/com/unciv/game/WorldScreen.java | 29 ++-- core/src/com/unciv/game/WorldTileGroup.java | 3 +- .../game/pickerscreens/PickerScreen.java | 8 +- .../{ => utils}/CameraStageBaseScreen.java | 9 +- .../{pickerscreens => utils}/GameSaver.java | 2 +- .../com/unciv/game/{ => utils}/HexMath.java | 2 +- .../unciv/game/{ => utils}/ImageGetter.java | 2 +- core/src/com/unciv/models/LinqCounter.java | 23 +++ core/src/com/unciv/models/LinqHashMap.java | 1 + .../com/unciv/models/gamebasics/Building.java | 8 +- 21 files changed, 470 insertions(+), 89 deletions(-) create mode 100644 core/src/com/unciv/game/ScienceVictoryScreen.java rename core/src/com/unciv/game/{ => utils}/CameraStageBaseScreen.java (88%) rename core/src/com/unciv/game/{pickerscreens => utils}/GameSaver.java (95%) rename core/src/com/unciv/game/{ => utils}/HexMath.java (99%) rename core/src/com/unciv/game/{ => utils}/ImageGetter.java (96%) create mode 100644 core/src/com/unciv/models/LinqCounter.java diff --git a/android/assets/jsons/Buildings.json b/android/assets/jsons/Buildings.json index f8e8dfe8fe..fd184f0001 100644 --- a/android/assets/jsons/Buildings.json +++ b/android/assets/jsons/Buildings.json @@ -3,12 +3,14 @@ { name:"Worker", description: "Can build improvements on tiles", + hurryCostModifier:20 cost:60 }, { name:"Settler", description: "Founds a new city", - cost:106 + cost:106, + hurryCostModifier:20 }, @@ -27,6 +29,7 @@ description: "Produces culture, enabling border growth", culture:2, cost:40, + hurryCostModifier:40, maintainance:1 }, { @@ -35,11 +38,13 @@ food:2, resourceBonusStats:{food:1}, maintainance:1, + hurryCostModifier:25, requiredTech:"Pottery" }, { name:"Library", description: "Adds 1 science for each 2 population in the city.", + hurryCostModifier:25, maintainance:1, unique:"SciencePer2Pop", requiredTech:"Writing" @@ -61,6 +66,7 @@ culture:3, requiredBuilding:"Monument", maintainance:2, + hurryCostModifier:25, requiredTech:"Philosophy" }, { @@ -86,6 +92,7 @@ maintainance:1, resourceBoostingBuilding:true, resourceBonusStats:{production:1}, + hurryCostModifier:25, requiredTech:"Horseback Riding" }, { @@ -110,12 +117,14 @@ description: "", maintainance:1, happiness:2, + hurryCostModifier:25, requiredTech:"Construction" }, { name:"Market", description: "", gold:2, + hurryCostModifier:25, percentStatBonus:{gold:25}, requiredTech:"Currency" }, @@ -133,6 +142,7 @@ maintainance:0, resourceBoostingBuilding:true, resourceBonusStats:{gold:2}, + hurryCostModifier:25, requiredTech:"Currency" }, { @@ -149,6 +159,7 @@ description: "40% of food is carried over after a new citizen is born", maintainance:1, food:2, + hurryCostModifier:25, unique:"FoodCarriesOver" requiredTech:"Engineering" }, @@ -157,6 +168,7 @@ description: "", maintainance:2, production:2, + hurryCostModifier:25, percentStatBonus:{production:15}, requiredTech:"Metal Casting" }, @@ -164,6 +176,7 @@ name:"Forge", description: "Iron provides +1 production", maintainance:1, + hurryCostModifier:25, resourceBoostingBuilding:true, resourceBonusStats:{production:1}, requiredTech:"Metal Casting" @@ -172,6 +185,7 @@ name:"University", description: "Jungles provide +2 science", maintainance:2, + hurryCostModifier:15, percentStatBonus:{science:33}, requiredBuilding:"Library", unique:"JunglesProvideScience", @@ -209,6 +223,7 @@ name:"Observatory", description: "City must be bordering a mountain", maintainance:2, + hurryCostModifier:25, percentStatBonus:{science:50}, requiredBuilding:"Library", requiredTech:"Metal Casting" @@ -217,6 +232,7 @@ name:"Opera House", description: "", culture:4, + hurryCostModifier:10, requiredBuilding:"Temple", maintainance:2, requiredTech:"Acoustics" @@ -233,6 +249,7 @@ name:"Bank", description: "", gold:2, + hurryCostModifier:15, percentStatBonus:{gold:25}, requiredBuilding:"Market", requiredTech:"Banking" @@ -241,6 +258,7 @@ name:"Theatre", description: "", happiness:3, + hurryCostModifier:10, maintainance:2, requiredBuilding:"Colloseum", requiredTech:"Banking" @@ -258,6 +276,7 @@ name:"Windmill", description: "", production:2, + hurryCostModifier:25, maintainance:2, percentStatBonus:{production:10}, requiredTech:"Economics" @@ -268,6 +287,7 @@ culture:5, requiredBuilding:"Opera House", maintainance:3, + hurryCostModifier:0, requiredTech:"Archaeology" }, { @@ -294,6 +314,7 @@ science:3, requiredBuilding:"University", maintainance:3, + hurryCostModifier:0, unique:"SciencePer2Pop", requiredTech:"Scientific Theory" }, @@ -303,6 +324,7 @@ food:5, requiredBuilding:"Aqueduct", maintainance:2, + hurryCostModifier:0, requiredTech:"Biology" }, { @@ -311,6 +333,7 @@ production:4, requiredBuilding:"Workshop", maintainance:3, + hurryCostModifier:0, requiredResource:"Coal", requiredTech:"Steam Power" }, @@ -319,6 +342,7 @@ description: "", gold:3, percentStatBonus:{gold:25}, + hurryCostModifier:15, requiredBuilding:"Bank", requiredTech:"Electricity" }, @@ -396,6 +420,70 @@ maintainance:2, requiredTech:"Mass Media" }, - - + { + name:"Solar Plant", + description: "Can only be built in cities next to deserts; cannot be built in a city with a Nuclear Plant", + production:5, + percentStatBonus:{production:15}, + requiredBuilding:"Factory", + maintainance:3, + cannotBeBuiltWith:"Nuclear Plant", + requiredTech:"Ecology", + unique:"MustBeNextToDesert" + }, + { + name:"Apollo Program", + description: "Allows the building of spaceship parts", + isWonder:true, + unique:"ApolloProgram", + requiredTech:"Rocketry" + }, + { + name:"Nuclear Plant", + description: "Can only be built in cities next to deserts; cannot be built in a city with a Nuclear Plant", + production:5, + percentStatBonus:{production:15}, + requiredBuilding:"Factory", + maintainance:3, + cannotBeBuiltWith:"Solar Plant", + requiredResource:"Uranium", + requiredTech:"Nuclear Fission" + }, + { + name:"Spaceship Factory", + description: "Increases production of spaceship parts by 50%", + production:3, + requiredResource:"Aluminum", + cost:360, + unique:"SpaceshipPartProductionBoost" + requiredTech:"Robotics" + }, + { + name:"SS Booster", + description: "Spaceship part", + requiredResource:"Aluminum", + requiredTech:"Robotics", + unique:"SpaceshipPart" + }, + { + name:"SS Cockpit", + description: "Spaceship part", + requiredResource:"Aluminum", + requiredTech:"Satellites", + unique:"SpaceshipPart" + }, + { + name:"SS Engine", + description: "Spaceship part", + requiredResource:"Aluminum", + requiredTech:"Particle Physics", + unique:"SpaceshipPart" + }, + { + name:"SS Statis Chamber", + description: "Spaceship part", + requiredResource:"Aluminum", + requiredTech:"Nanotechnology", + unique:"SpaceshipPart" + } ] \ No newline at end of file diff --git a/android/assets/jsons/Techs.json b/android/assets/jsons/Techs.json index 0fddbb6b7b..6434d07320 100644 --- a/android/assets/jsons/Techs.json +++ b/android/assets/jsons/Techs.json @@ -419,7 +419,7 @@ { name:"Electronics", row:5, - prerequisites:["Electricity"], + prerequisites:["Telegraph"], description:"Contributes only war-relatied things - on hold until AI is introduced - todo" }, { name:"Mass Media", @@ -440,5 +440,166 @@ description:"Contributes only war-relatied things - on hold until AI is introduced - todo" } ] + }, + { + columnNumber: 13, + techCost: 7035, + buildingCost:500, + techs:[ + { + name:"Ecology", + row:2, + prerequisites:["Penicillin","Plastics"], + description:"Enables construction of Solar Plants on cities near deserts, increasing production" + }, + { + name:"Computers", + row:4, + prerequisites:["Electronics","Mass Media","Radar"], + description:"Contributes only war-relatied things - on hold until AI is introduced - todo" + }, + { + name:"Rocketry", + row:6, + prerequisites:["Radar"], + description:"Contributes only war-relatied things - on hold until AI is introduced - todo" }, + { + name:"Lasers", + row:8, + prerequisites:["Radar"], + description:"Contributes only war-relatied things - on hold until AI is introduced - todo" + }, + { + name:"Nuclear Fission", + row:10, + prerequisites:["Atomic Theory"], + description:"Allows construction of Nuclear Plants, increasing production" + } + ] + }, + { + columnNumber: 14, + techCost: 8465, + buildingCost:750, + techs:[ + { + name:"Globalization", + row:2, + cost:10445, + prerequisites:["Ecology","Computers"], + description:"Theoretically enables united nation - tthere's no ai so we'll leave it be for now" + }, + { + name:"Robotics", + row:4, + prerequisites:["Computers"], + description:"Allow construction of SS Boosters, a vital part of the spaceship, and the Spaceship Factory, which speeds the production of spaceship parts" + }, + { + name:"Satellites", + row:6, + prerequisites:["Rocketry"], + description:"Allow construction of the SS Cockpit, a vital part of the spaceship" + }, + { + name:"Stealth", + row:8, + prerequisites:["Lasers"], + description:"Contributes only war-relatied things - on hold until AI is introduced - todo" + }, + { + name:"Advanced Ballistics", + row:10, + prerequisites:["Atomic Theory"], + description:"Contributes only war-relatied things - on hold until AI is introduced - todo" + } + ] + }, + { + columnNumber: 15, + techCost: 9675, + buildingCost:750, + wonderCost:1250, + techs:[ + { + name:"Robotics", + row:4, + prerequisites:["Computers"], + description:"Allow construction of SS Boosters, a vital part of the spaceship, and the Spaceship Factory, which speeds the production of spaceship parts" + }, + { + name:"Satellites", + row:6, + prerequisites:["Rocketry"], + description:"Allow construction of the SS Cockpit, a vital part of the spaceship" + }, + { + name:"Stealth", + row:8, + prerequisites:["Lasers"], + description:"Contributes only war-relatied things - on hold until AI is introduced - todo" + }, + { + name:"Advanced Ballistics", + row:10, + prerequisites:["Atomic Theory"], + description:"Contributes only war-relatied things - on hold until AI is introduced - todo" + } + ] + }, + { + columnNumber: 16, + techCost: 9675, + buildingCost:750, + wonderCost:1250, + techs:[ + { + name:"Particle Physics", + row:5, + prerequisites:["Ecology","Computers"], + description:"Allow construction of the SS Engine, a vital part of the spaceship" + }, + { + name:"Nuclear Fusion", + row:8, + prerequisites:["Satellites","Stealth","Advanced Ballistics"], + description:"Theoretically enables united nation - tthere's no ai so we'll leave it be for now" + } + ] + } + { + columnNumber: 16, + techCost: 9675, + buildingCost:750, + wonderCost:1250, + techs:[ + { + name:"Globalization", + row:2, + cost:10445, + prerequisites:["Ecology","Computers"], + description:"Theoretically enables united nation - tthere's no ai so we'll leave it be for now" + }, + { + name:"Nanotechnology", + row:5, + prerequisites:["Particle Physics"], + description:"Allow construction of the SS Statis Chamber, a vital part of the spaceship" + } + ] + } + { + columnNumber: 16, + techCost: 9675, + buildingCost:750, + wonderCost:1250, + techs:[ + { + name:"Future Tech", + row:5, + prerequisites:["Globalization","Nanotechnology","Nuclear Fusion"], + description:"Who knows what the future holds?" + } + ] } ] \ No newline at end of file diff --git a/core/src/com/unciv/civinfo/CityBuildings.java b/core/src/com/unciv/civinfo/CityBuildings.java index 5b2be4a79a..8723d50934 100644 --- a/core/src/com/unciv/civinfo/CityBuildings.java +++ b/core/src/com/unciv/civinfo/CityBuildings.java @@ -28,6 +28,7 @@ public class CityBuildings public LinqCollection builtBuildings = new LinqCollection(); public HashMap inProgressBuildings = new HashMap(); public String currentBuilding = Worker; // default starting building! + public Building getCurrentBuilding(){return getGameBuilding(currentBuilding);} public CityInfo getCity(){return UnCivGame.Current.civInfo.tileMap.get(cityLocation).getCity(); } public boolean isBuilt(String buildingName) { return builtBuildings.contains(buildingName); } @@ -53,6 +54,8 @@ public class CityBuildings { if (currentBuilding.equals(Worker) || currentBuilding.equals(Settler)) UnCivGame.Current.civInfo.tileMap.get(cityLocation).unit = new Unit(currentBuilding,2); + else if("SpaceshipPart".equals(getGameBuilding(currentBuilding).unique)) + CivilizationInfo.current().spaceshipParts.add(currentBuilding,1); else { @@ -68,20 +71,24 @@ public class CityBuildings CivilizationInfo.current().notifications.add(currentBuilding+" has been built in "+getCity().name); // Choose next building to build - currentBuilding = getBuildableBuildings().first(new Predicate() { - @Override - public boolean evaluate(String arg0) { - if(arg0.equals(Settler) || arg0.equals(Worker)) return false; - return !builtBuildings.contains(arg0); - } - }); - if (currentBuilding == null) currentBuilding = Worker; + chooseNextBuilding(); CivilizationInfo.current().notifications.add("Work has started on "+currentBuilding); } } + private void chooseNextBuilding() { + currentBuilding = getBuildableBuildings().first(new Predicate() { + @Override + public boolean evaluate(String arg0) { + if(arg0.equals(Settler) || arg0.equals(Worker) || getGameBuilding(arg0).isWonder) return false; + return !builtBuildings.contains(arg0); + } + }); + if (currentBuilding == null) currentBuilding = Worker; + } + public boolean canBuild(final Building building) { CivilizationInfo civInfo = UnCivGame.Current.civInfo; @@ -116,9 +123,19 @@ public class CityBuildings return arg0.cityBuildings.isBuilt(building.requiredBuildingInAllCities); } }) ) return false; + if(building.cannotBeBuiltWith != null && isBuilt(building.cannotBeBuiltWith)) return false; + if("MustBeNextToDesert".equals(building.unique) && + !civInfo.tileMap.getTilesInDistance(cityLocation,1).any(new Predicate() { + @Override + public boolean evaluate(TileInfo arg0) { + return arg0.baseTerrain.equals("Desert"); + } + })) + return false; if(building.requiredResource!=null && !civInfo.getCivResources().keySet().contains(GameBasics.TileResources.get(building.requiredResource))) return false; // Only checks if exists, doesn't check amount - todo + if(building.unique.equals("SpaceshipPart") && !civInfo.getBuildingUniques().contains("ApolloProgram")) return false; return true; } @@ -167,19 +184,29 @@ public class CityBuildings return stats; } + public int workDone(String buildingName) { + if (inProgressBuildings.containsKey(buildingName)) + return inProgressBuildings.get(buildingName); + return 0; + } + 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 ;) + float workLeft = getGameBuilding(buildingName).cost - workDone(buildingName); // needs to be float so that we get the cieling properly ;) - FullStats cityStats = getCity().getCityStats(); + FullStats cityStats = getCity().cityStats; int production = Math.round(cityStats.production); if (buildingName.equals(Settler)) production += cityStats.food; return (int) Math.ceil(workLeft / production); } + public void purchaseBuilding(String buildingName) { + CivilizationInfo.current().civStats.gold -= getGameBuilding(buildingName).getGoldCost(); + builtBuildings.add(buildingName); + if(currentBuilding.equals(buildingName)) chooseNextBuilding(); + } + public String getCityProductionText(){ String result = currentBuilding; if(!result.equals("Science") && !result.equals("Gold")) diff --git a/core/src/com/unciv/civinfo/CityInfo.java b/core/src/com/unciv/civinfo/CityInfo.java index acd1716d57..ff7b8d5b88 100644 --- a/core/src/com/unciv/civinfo/CityInfo.java +++ b/core/src/com/unciv/civinfo/CityInfo.java @@ -4,15 +4,13 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Predicate; import com.unciv.game.UnCivGame; import com.unciv.models.LinqCollection; +import com.unciv.models.LinqCounter; import com.unciv.models.LinqHashMap; import com.unciv.models.gamebasics.Building; import com.unciv.models.gamebasics.GameBasics; -import com.unciv.models.gamebasics.ResourceType; import com.unciv.models.gamebasics.TileResource; import com.unciv.models.stats.FullStats; -import java.util.ArrayList; - public class CityInfo { public final Vector2 cityLocation; public String name; @@ -23,6 +21,8 @@ public class CityInfo { public int population = 1; public int foodStored = 0; + public FullStats cityStats; // This is so we won't have to calculate this multiple times - takes a lot of time, especially on phones! + private TileMap getTileMap(){return UnCivGame.Current.civInfo.tileMap; } public TileInfo getTile(){return getTileMap().get(cityLocation);} @@ -56,6 +56,8 @@ public class CityInfo { name = CityNames[civInfo.cities.size()]; this.cityLocation = cityLocation; cityBuildings = new CityBuildings(this); + if(civInfo.cities.size()==0) cityBuildings.builtBuildings.add("Palace"); + civInfo.cities.add(this); for(TileInfo tileInfo : civInfo.tileMap.getTilesInDistance(cityLocation,1)) { tileInfo.owner = civInfo.civName; @@ -68,25 +70,22 @@ public class CityInfo { tile.terrainFeature=null; autoAssignWorker(); - civInfo.cities.add(this); + updateCityStats(); } - public LinqHashMap getCityResources(){ - LinqHashMap cityResources = new LinqHashMap(); + public LinqCounter getCityResources(){ + LinqCounter cityResources = new LinqCounter(); for (TileInfo tileInfo : getTilesInRange()) { TileResource resource = tileInfo.getTileResource(); - if (resource != null && (resource.improvement.equals(tileInfo.improvement) || tileInfo.isCityCenter())){ - if(cityResources.containsKey(resource)) cityResources.put(resource,cityResources.get(resource)+1); - else cityResources.put(resource,1); - } + if (resource != null && (resource.improvement.equals(tileInfo.improvement) || tileInfo.isCityCenter())) + cityResources.add(resource,1); } // Remove resources required by buildings for(Building building : cityBuildings.getBuiltBuildings()){ if(building.requiredResource!=null){ TileResource resource = GameBasics.TileResources.get(building.requiredResource); - if(cityResources.containsKey(resource)) cityResources.put(resource,cityResources.get(resource)-1); - else cityResources.put(resource,-1); + cityResources.add(resource,-1); } } return cityResources; @@ -109,7 +108,7 @@ public class CityInfo { return getFreePopulation() > 0; } - public FullStats getCityStats() { + public void updateCityStats() { FullStats stats = new FullStats(); stats.science += population; @@ -133,7 +132,7 @@ public class CityInfo { stats.add(cityBuildings.getStats()); FullStats statPercentBonuses = cityBuildings.getStatPercentBonuses(); - if(isConnectedToCapital(RoadStatus.Railroad)) statPercentBonuses.production += 25; + if(isCapital() || isConnectedToCapital(RoadStatus.Railroad)) statPercentBonuses.production += 25; stats.food*=1+statPercentBonuses.food/100; stats.gold*=1+statPercentBonuses.gold/100; stats.production*=1+statPercentBonuses.production/100; @@ -143,8 +142,7 @@ public class CityInfo { stats.gold-=cityBuildings.getMaintainanceCosts(); // this is AFTER the bonus calculation! if(CivilizationInfo.current().getHappinessForNextTurn() < 0) stats.food /= 4; // Reduce excess food to 1/4 - - return stats; + this.cityStats = stats; } public float getCityHappiness(){ // needs to be a separate function because we need to know the global happiness state @@ -154,8 +152,7 @@ public class CityInfo { } void nextTurn() { - FullStats stats = getCityStats(); - + FullStats stats = cityStats; if (cityBuildings.currentBuilding.equals(CityBuildings.Settler) && stats.food > 0) { stats.production += stats.food; stats.food = 0; diff --git a/core/src/com/unciv/civinfo/CivilizationInfo.java b/core/src/com/unciv/civinfo/CivilizationInfo.java index 59a3983e0d..3d735ac742 100644 --- a/core/src/com/unciv/civinfo/CivilizationInfo.java +++ b/core/src/com/unciv/civinfo/CivilizationInfo.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Predicate; import com.unciv.game.UnCivGame; import com.unciv.models.LinqCollection; +import com.unciv.models.LinqCounter; import com.unciv.models.LinqHashMap; import com.unciv.models.gamebasics.Building; import com.unciv.models.gamebasics.GameBasics; @@ -12,7 +13,6 @@ import com.unciv.models.gamebasics.TileResource; import com.unciv.models.stats.CivStats; import java.util.Collection; -import java.util.HashSet; /** * Created by LENOVO on 10/18/2017. @@ -31,13 +31,13 @@ public class CivilizationInfo { public LinqCollection cities = new LinqCollection(); public TileMap tileMap = new TileMap(20); + public LinqCounter spaceshipParts = new LinqCounter(); public int currentCity =0; //index! public CivilizationInfo(){ } - public CityInfo getCurrentCity() { return cities.get(currentCity); } public int turnsToTech(String TechName) { @@ -47,7 +47,6 @@ public class CivilizationInfo { public void addCity(Vector2 location){ CityInfo city = new CityInfo(this,location); - if(cities.size()==1) city.cityBuildings.builtBuildings.add("Palace"); } public CityInfo getCapital(){ @@ -71,13 +70,14 @@ public class CivilizationInfo { for(TileInfo tile : tileMap.values()) tile.nextTurn(); + for (CityInfo city : cities) city.updateCityStats(); turns += 1; } public CivStats getStatsForNextTurn() { CivStats statsForTurn = new CivStats(); for (CityInfo city : cities) { - statsForTurn.add(city.getCityStats()); + statsForTurn.add(city.cityStats); } statsForTurn.happiness = getHappinessForNextTurn(); return statsForTurn; @@ -97,14 +97,10 @@ public class CivilizationInfo { return happiness; } - public LinqHashMap getCivResources(){ - LinqHashMap civResources = new LinqHashMap(); - for (CityInfo city : cities) { - for(TileResource resource : city.getCityResources().keySet()){ - if(civResources.containsKey(resource)) civResources.put(resource,civResources.get(resource)+1); - else civResources.put(resource,1); - } - } + public LinqCounter getCivResources(){ + LinqCounter civResources = new LinqCounter(); + for (CityInfo city : cities) civResources.add(city.getCityResources()); + return civResources; } diff --git a/core/src/com/unciv/civinfo/TileMap.java b/core/src/com/unciv/civinfo/TileMap.java index 757b79833b..d9098adea4 100644 --- a/core/src/com/unciv/civinfo/TileMap.java +++ b/core/src/com/unciv/civinfo/TileMap.java @@ -2,7 +2,7 @@ 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.utils.HexMath; import com.unciv.models.LinqCollection; import com.unciv.models.LinqHashMap; import com.unciv.models.gamebasics.GameBasics; diff --git a/core/src/com/unciv/game/CityScreen.java b/core/src/com/unciv/game/CityScreen.java index d823a50f40..2156d9ff1b 100644 --- a/core/src/com/unciv/game/CityScreen.java +++ b/core/src/com/unciv/game/CityScreen.java @@ -8,6 +8,7 @@ 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; @@ -21,13 +22,15 @@ 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.game.pickerscreens.PickerScreen; +import com.unciv.models.gamebasics.Building; import com.unciv.models.stats.FullStats; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; -public class CityScreen extends CameraStageBaseScreen { +public class CityScreen extends com.unciv.game.utils.CameraStageBaseScreen { TileInfo selectedTile = null; float buttonScale = game.settings.buttonScale; @@ -141,12 +144,13 @@ public class CityScreen extends CameraStageBaseScreen { public void clicked(InputEvent event, float x, float y) { if(tileInfo.workingCity ==null && cityInfo.getFreePopulation() > 0) tileInfo.workingCity = cityInfo.name; else if(cityInfo.name.equals(tileInfo.workingCity)) tileInfo.workingCity = null; + cityInfo.updateCityStats(); updateCityTable(); } }); } - Vector2 positionalVector = HexMath.Hex2WorldCoords(tileInfo.position.cpy().sub(cityInfo.cityLocation)); + Vector2 positionalVector = com.unciv.game.utils.HexMath.Hex2WorldCoords(tileInfo.position.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); @@ -185,8 +189,8 @@ public class CityScreen extends CameraStageBaseScreen { } private void updateCityTable() { - CityInfo cityInfo = game.civInfo.getCurrentCity(); - FullStats stats = cityInfo.getCityStats(); + final CityInfo cityInfo = game.civInfo.getCurrentCity(); + FullStats stats = cityInfo.cityStats; CityStatsTable.pad(20); CityStatsTable.columnDefaults(0).padRight(10); CityStatsTable.clear(); @@ -198,7 +202,9 @@ public class CityScreen extends CameraStageBaseScreen { CityStatsTable.row(); HashMap CityStatsValues = new LinkedHashMap(); - CityStatsValues.put("Production",Math.round(stats.production) +""); + CityStatsValues.put("Production",Math.round(stats.production) + +" ("+ cityInfo.cityBuildings.workDone(cityInfo.cityBuildings.currentBuilding) + +"/"+cityInfo.cityBuildings.getCurrentBuilding().cost+")"); CityStatsValues.put("Food",Math.round(stats.food) +" ("+cityInfo.foodStored+"/"+cityInfo.foodToNextPopulation()+")"); CityStatsValues.put("Gold",Math.round(stats.gold) +""); @@ -208,7 +214,7 @@ public class CityScreen extends CameraStageBaseScreen { CityStatsValues.put("Population",cityInfo.getFreePopulation()+"/"+cityInfo.population); for(String key : CityStatsValues.keySet()){ - CityStatsTable.add(ImageGetter.getStatIcon(key)).align(Align.right); + CityStatsTable.add(com.unciv.game.utils.ImageGetter.getStatIcon(key)).align(Align.right); CityStatsTable.add(new Label(CityStatsValues.get(key),skin)).align(Align.left); CityStatsTable.row(); } @@ -229,6 +235,30 @@ public class CityScreen extends CameraStageBaseScreen { CityStatsTable.add(buildingPickButton).colspan(2).pad(10) .size(buildingPickButton.getWidth()*buttonScale,buildingPickButton.getHeight()*buttonScale); + + // https://forums.civfanatics.com/threads/rush-buying-formula.393892/ + + Building building = cityInfo.cityBuildings.getCurrentBuilding(); + if(!building.isWonder) { + CityStatsTable.row(); + int buildingGoldCost = building.getGoldCost(); + TextButton buildingBuyButton = new TextButton("Buy for \r\n"+buildingGoldCost+" gold", skin); + buildingBuyButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + cityInfo.cityBuildings.purchaseBuilding(cityInfo.cityBuildings.currentBuilding); + updateCityTable(); + } + }); + if(buildingGoldCost > game.civInfo.civStats.gold){ + buildingBuyButton.setColor(Color.GRAY); + buildingBuyButton.setTouchable(Touchable.disabled); + } + buildingBuyButton.getLabel().setFontScale(buttonScale); + CityStatsTable.add(buildingBuyButton).colspan(2).pad(10) + .size(buildingBuyButton.getWidth() * buttonScale, buildingBuyButton.getHeight() * buttonScale); + } + CityStatsTable.setPosition(10,10); CityStatsTable.pack(); } @@ -259,7 +289,7 @@ public class CityScreen extends CameraStageBaseScreen { for(String key : TileStatsValues.keySet()){ if(TileStatsValues.get(key) == 0) continue; // this tile gives nothing of this stat, so why even display it? - TileTable.add(ImageGetter.getStatIcon(key)).align(Align.right); + TileTable.add(com.unciv.game.utils.ImageGetter.getStatIcon(key)).align(Align.right); TileTable.add(new Label(Math.round(TileStatsValues.get(key))+"",skin)).align(Align.left); TileTable.row(); } diff --git a/core/src/com/unciv/game/CivilopediaScreen.java b/core/src/com/unciv/game/CivilopediaScreen.java index 377bb18506..a31ad972d9 100644 --- a/core/src/com/unciv/game/CivilopediaScreen.java +++ b/core/src/com/unciv/game/CivilopediaScreen.java @@ -20,7 +20,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; -public class CivilopediaScreen extends CameraStageBaseScreen { +public class CivilopediaScreen extends com.unciv.game.utils.CameraStageBaseScreen { public CivilopediaScreen(final UnCivGame game) { super(game); diff --git a/core/src/com/unciv/game/ScienceVictoryScreen.java b/core/src/com/unciv/game/ScienceVictoryScreen.java new file mode 100644 index 0000000000..87d1d5d11a --- /dev/null +++ b/core/src/com/unciv/game/ScienceVictoryScreen.java @@ -0,0 +1,41 @@ +package com.unciv.game; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.scenes.scene2d.Touchable; +import com.badlogic.gdx.scenes.scene2d.ui.Button; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.unciv.civinfo.CivilizationInfo; +import com.unciv.game.pickerscreens.PickerScreen; +import com.unciv.models.LinqCounter; + +public class ScienceVictoryScreen extends PickerScreen { + + public ScienceVictoryScreen(UnCivGame game) { + super(game); + LinqCounter spaceshipParts = new LinqCounter(); + spaceshipParts.add(game.civInfo.spaceshipParts); + + for (int i = 0; i < 3; i++) { + addPartButton("SS Booster",spaceshipParts); + } + addPartButton("SS Cockpit",spaceshipParts); + addPartButton("SS Engine",spaceshipParts); + addPartButton("SS Statis Chamber",spaceshipParts); + rightSideButton.setVisible(false); + + if(!game.civInfo.getBuildingUniques().contains("ApolloProject")) + descriptionLabel.setText("You must build the Apollo Project before you can build spaceship parts!"); + else descriptionLabel.setText("Apollo project is built - you may construct spaceship parts in your cities!"); + } + + private void addPartButton(String partName, LinqCounter parts){ + topTable.row(); + TextButton button = new TextButton(partName,skin); + button.setTouchable(Touchable.disabled); + if (parts.get(partName)>0){ + button.setColor(Color.GREEN); + parts.add(partName,-1); + } + topTable.add(button).pad(10); + } +} diff --git a/core/src/com/unciv/game/TileGroup.java b/core/src/com/unciv/game/TileGroup.java index 69dcd4b4b1..1c4e565a07 100644 --- a/core/src/com/unciv/game/TileGroup.java +++ b/core/src/com/unciv/game/TileGroup.java @@ -30,14 +30,14 @@ public class TileGroup extends Group { terrainType = tileInfo.getLastTerrain().name; String terrainFileName = "TerrainIcons/" + terrainType.replace(' ','_') + "_(Civ5).png"; - terrainImage = ImageGetter.getImageByFilename(terrainFileName); + terrainImage = com.unciv.game.utils.ImageGetter.getImageByFilename(terrainFileName); terrainImage.setSize(50,50); addActor(terrainImage); } void addPopulationIcon(){ - populationImage = ImageGetter.getStatIcon("Population"); + populationImage = com.unciv.game.utils.ImageGetter.getStatIcon("Population"); populationImage.moveBy(0, terrainImage.getHeight()-populationImage.getHeight()); // top left addActor(populationImage); } @@ -54,12 +54,12 @@ public class TileGroup extends Group { if(!terrainType.equals(tileInfo.getLastTerrain().name)) { terrainType = tileInfo.getLastTerrain().name; String terrainFileName = "TerrainIcons/" + terrainType.replace(' ', '_') + "_(Civ5).png"; - terrainImage.setDrawable(new TextureRegionDrawable(ImageGetter.textureRegionByFileName.get(terrainFileName))); // In case we e.g. removed a jungle + terrainImage.setDrawable(new TextureRegionDrawable(com.unciv.game.utils.ImageGetter.textureRegionByFileName.get(terrainFileName))); // In case we e.g. removed a jungle } if (tileInfo.hasViewableResource() && resourceImage == null) { // Need to add the resource image! String fileName = "ResourceIcons/" + tileInfo.resource + "_(Civ5).png"; - Image image = ImageGetter.getImageByFilename(fileName); + Image image = com.unciv.game.utils.ImageGetter.getImageByFilename(fileName); image.setSize(20,20); image.moveBy(terrainImage.getWidth()-image.getWidth(), 0); // bottom right resourceImage = image; @@ -67,7 +67,7 @@ public class TileGroup extends Group { } if (tileInfo.unit != null && unitImage == null) { - unitImage = ImageGetter.getImageByFilename("StatIcons/" + tileInfo.unit.Name + "_(Civ5).png"); + unitImage = com.unciv.game.utils.ImageGetter.getImageByFilename("StatIcons/" + tileInfo.unit.Name + "_(Civ5).png"); addActor(unitImage); unitImage.setSize(20, 20); // not moved - is at bottom left } @@ -84,7 +84,7 @@ public class TileGroup extends Group { if (tileInfo.improvement != null && improvementImage == null) { - improvementImage = ImageGetter.getImageByFilename("ImprovementIcons/" + tileInfo.improvement.replace(' ','_') + "_(Civ5).png"); + improvementImage = com.unciv.game.utils.ImageGetter.getImageByFilename("ImprovementIcons/" + tileInfo.improvement.replace(' ','_') + "_(Civ5).png"); addActor(improvementImage); improvementImage.setSize(20, 20); improvementImage.moveBy(terrainImage.getWidth()-improvementImage.getWidth(), @@ -101,11 +101,11 @@ public class TileGroup extends Group { if (neighbor == tileInfo || neighbor.roadStatus == RoadStatus.None) continue; if (roadImages.containsKey(neighbor.position.toString())) continue; - Image image = ImageGetter.getImageByFilename("TerrainIcons/road.png"); + Image image = com.unciv.game.utils.ImageGetter.getImageByFilename("TerrainIcons/road.png"); roadImages.put(neighbor.position.toString(), image); Vector2 relativeHexPosition = tileInfo.position.cpy().sub(neighbor.position); - Vector2 relativeWorldPosition = HexMath.Hex2WorldCoords(relativeHexPosition); + Vector2 relativeWorldPosition = com.unciv.game.utils.HexMath.Hex2WorldCoords(relativeHexPosition); // This is some crazy voodoo magic so I'll explain. image.moveBy(25, 25); // Move road to center of tile diff --git a/core/src/com/unciv/game/UnCivGame.java b/core/src/com/unciv/game/UnCivGame.java index 047d995631..69c00cfc24 100644 --- a/core/src/com/unciv/game/UnCivGame.java +++ b/core/src/com/unciv/game/UnCivGame.java @@ -4,9 +4,10 @@ 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.CityInfo; import com.unciv.civinfo.CivilizationInfo; import com.unciv.civinfo.Unit; -import com.unciv.game.pickerscreens.GameSaver; +import com.unciv.game.utils.GameSaver; import com.unciv.models.gamebasics.BasicHelp; import com.unciv.models.gamebasics.Building; import com.unciv.models.gamebasics.GameBasics; @@ -31,6 +32,9 @@ public class UnCivGame extends Game { if(GameSaver.GetSave("Autosave").exists()) { try { GameSaver.LoadGame(this, "Autosave"); + for (CityInfo city : this.civInfo.cities) { + if(city.cityStats == null) city.updateCityStats(); + } } catch(Exception ex){ // silent fail if we can't read the autosave startNewGame(); } diff --git a/core/src/com/unciv/game/WorldScreen.java b/core/src/com/unciv/game/WorldScreen.java index 830742b225..48e139c4c0 100644 --- a/core/src/com/unciv/game/WorldScreen.java +++ b/core/src/com/unciv/game/WorldScreen.java @@ -8,7 +8,6 @@ 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.List; import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; @@ -17,12 +16,11 @@ 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.Array; import com.badlogic.gdx.utils.Predicate; 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.game.utils.*; import com.unciv.models.LinqHashMap; import com.unciv.models.gamebasics.GameBasics; import com.unciv.models.gamebasics.TileImprovement; @@ -32,7 +30,7 @@ import com.unciv.models.stats.FullStats; import java.util.HashMap; import java.util.HashSet; -public class WorldScreen extends CameraStageBaseScreen { +public class WorldScreen extends com.unciv.game.utils.CameraStageBaseScreen { TileInfo selectedTile = null; @@ -80,7 +78,6 @@ public class WorldScreen extends CameraStageBaseScreen { } private void addNotificationsList() { -// NotificationsTable.setBackground(TileTable.getBackground()); stage.addActor(NotificationsTable); } private void updateNotificationsList() { @@ -128,8 +125,18 @@ public class WorldScreen extends CameraStageBaseScreen { }); OptionsTable.add(StartNewGameButton).pad(10); OptionsTable.row(); - - + + TextButton OpenScienceVictoryScreen = new TextButton("Science victory status",skin); + OpenScienceVictoryScreen.addListener(new ClickListener(){ + @Override + public void clicked(InputEvent event, float x, float y) { + game.setScreen(new ScienceVictoryScreen(game)); + } + }); + OptionsTable.add(OpenScienceVictoryScreen).pad(10); + OptionsTable.row(); + + TextButton closeButton = new TextButton("Close",skin); closeButton.addListener(new ClickListener(){ @Override @@ -251,7 +258,7 @@ public class WorldScreen extends CameraStageBaseScreen { }); - Vector2 positionalVector = HexMath.Hex2WorldCoords(tileInfo.position); + Vector2 positionalVector = com.unciv.game.utils.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); @@ -323,7 +330,7 @@ public class WorldScreen extends CameraStageBaseScreen { for(String key : TileStatsValues.keySet()){ if(TileStatsValues.get(key) == 0) continue; // this tile gives nothing of this stat, so why even display it? - TileTable.add(ImageGetter.getStatIcon(key)).align(Align.right); + TileTable.add(com.unciv.game.utils.ImageGetter.getStatIcon(key)).align(Align.right); TileTable.add(new Label(Math.round(TileStatsValues.get(key))+"",skin)).align(Align.left); TileTable.row(); } @@ -434,7 +441,7 @@ public class WorldScreen extends CameraStageBaseScreen { // tiles adjacent to city tiles for(TileInfo tileInfo : game.civInfo.tileMap.values()) if(game.civInfo.civName.equals(tileInfo.owner)) - for(Vector2 adjacentLocation : HexMath.GetAdjacentVectors(tileInfo.position)) + for(Vector2 adjacentLocation : com.unciv.game.utils.HexMath.GetAdjacentVectors(tileInfo.position)) ViewableVectorStrings.add(adjacentLocation.toString()); // Tiles within 2 tiles of units @@ -445,7 +452,7 @@ public class WorldScreen extends CameraStageBaseScreen { return arg0.unit !=null; } })) - for(Vector2 vector : HexMath.GetVectorsInDistance(tile.position,2)) + for(Vector2 vector : com.unciv.game.utils.HexMath.GetVectorsInDistance(tile.position,2)) ViewableVectorStrings.add(vector.toString()); for(String string : ViewableVectorStrings) diff --git a/core/src/com/unciv/game/WorldTileGroup.java b/core/src/com/unciv/game/WorldTileGroup.java index cf7bcaa771..7cbbb10946 100644 --- a/core/src/com/unciv/game/WorldTileGroup.java +++ b/core/src/com/unciv/game/WorldTileGroup.java @@ -8,7 +8,6 @@ import com.unciv.civinfo.CityInfo; import com.unciv.civinfo.TileInfo; - public class WorldTileGroup extends TileGroup { WorldTileGroup(TileInfo tileInfo) { @@ -29,7 +28,7 @@ public class WorldTileGroup extends TileGroup { if (tileInfo.owner != null && hexagon == null) { - hexagon = ImageGetter.getImageByFilename("TerrainIcons/Hexagon.png"); + hexagon = com.unciv.game.utils.ImageGetter.getImageByFilename("TerrainIcons/Hexagon.png"); float imageScale = terrainImage.getWidth() * 1.3f / hexagon.getWidth(); hexagon.setScale(imageScale); hexagon.setPosition((getWidth() - hexagon.getWidth() * imageScale) / 2, diff --git a/core/src/com/unciv/game/pickerscreens/PickerScreen.java b/core/src/com/unciv/game/pickerscreens/PickerScreen.java index bef4b83309..5fd1a7a5af 100644 --- a/core/src/com/unciv/game/pickerscreens/PickerScreen.java +++ b/core/src/com/unciv/game/pickerscreens/PickerScreen.java @@ -8,16 +8,16 @@ 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.utils.CameraStageBaseScreen; import com.unciv.game.UnCivGame; public class PickerScreen extends CameraStageBaseScreen { TextButton closeButton; - Label descriptionLabel; - TextButton rightSideButton; + protected Label descriptionLabel; + protected TextButton rightSideButton; float screenSplit = 0.85f; - Table topTable; + protected Table topTable; SplitPane splitPane; diff --git a/core/src/com/unciv/game/CameraStageBaseScreen.java b/core/src/com/unciv/game/utils/CameraStageBaseScreen.java similarity index 88% rename from core/src/com/unciv/game/CameraStageBaseScreen.java rename to core/src/com/unciv/game/utils/CameraStageBaseScreen.java index 2ff0263d0d..63e7aaf461 100644 --- a/core/src/com/unciv/game/CameraStageBaseScreen.java +++ b/core/src/com/unciv/game/utils/CameraStageBaseScreen.java @@ -1,4 +1,4 @@ -package com.unciv.game; +package com.unciv.game.utils; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Screen; @@ -13,14 +13,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.utils.viewport.ExtendViewport; import com.badlogic.gdx.utils.viewport.FitViewport; import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.unciv.game.UnCivGame; 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")); + public UnCivGame game; + public Stage stage; + public Skin skin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); static Batch batch = new SpriteBatch(); diff --git a/core/src/com/unciv/game/pickerscreens/GameSaver.java b/core/src/com/unciv/game/utils/GameSaver.java similarity index 95% rename from core/src/com/unciv/game/pickerscreens/GameSaver.java rename to core/src/com/unciv/game/utils/GameSaver.java index 45765e5422..e6412f2a9b 100644 --- a/core/src/com/unciv/game/pickerscreens/GameSaver.java +++ b/core/src/com/unciv/game/utils/GameSaver.java @@ -1,4 +1,4 @@ -package com.unciv.game.pickerscreens; +package com.unciv.game.utils; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; diff --git a/core/src/com/unciv/game/HexMath.java b/core/src/com/unciv/game/utils/HexMath.java similarity index 99% rename from core/src/com/unciv/game/HexMath.java rename to core/src/com/unciv/game/utils/HexMath.java index ef5c1915e1..646d190d4a 100644 --- a/core/src/com/unciv/game/HexMath.java +++ b/core/src/com/unciv/game/utils/HexMath.java @@ -1,4 +1,4 @@ -package com.unciv.game; +package com.unciv.game.utils; import com.badlogic.gdx.math.Vector2; import com.unciv.models.LinqCollection; diff --git a/core/src/com/unciv/game/ImageGetter.java b/core/src/com/unciv/game/utils/ImageGetter.java similarity index 96% rename from core/src/com/unciv/game/ImageGetter.java rename to core/src/com/unciv/game/utils/ImageGetter.java index d9290e0747..84a92d6307 100644 --- a/core/src/com/unciv/game/ImageGetter.java +++ b/core/src/com/unciv/game/utils/ImageGetter.java @@ -1,4 +1,4 @@ -package com.unciv.game; +package com.unciv.game.utils; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; diff --git a/core/src/com/unciv/models/LinqCounter.java b/core/src/com/unciv/models/LinqCounter.java new file mode 100644 index 0000000000..5f5f24f82a --- /dev/null +++ b/core/src/com/unciv/models/LinqCounter.java @@ -0,0 +1,23 @@ +package com.unciv.models; + +import java.util.LinkedHashMap; + +public class LinqCounter extends LinkedHashMap { + + public Integer get(Object key){ // don't return null if empty + if(containsKey(key)) return super.get(key); + else return 0; + } + + public void add(K key, int value){ + if(!containsKey(key)) put(key,value); + else put(key,get(key)+value); + if(get(key)==0) remove(key); // No objects of this sort left, no need to count + } + + public void add(LinqCounter other){ + for (K key : other.keySet()) { + add(key,other.get(key)); + } + } +} diff --git a/core/src/com/unciv/models/LinqHashMap.java b/core/src/com/unciv/models/LinqHashMap.java index 278ee1fd56..ba58b71dc4 100644 --- a/core/src/com/unciv/models/LinqHashMap.java +++ b/core/src/com/unciv/models/LinqHashMap.java @@ -7,3 +7,4 @@ public class LinqHashMap extends LinkedHashMap { return new LinqCollection(super.values()); } } + diff --git a/core/src/com/unciv/models/gamebasics/Building.java b/core/src/com/unciv/models/gamebasics/Building.java index 32b8567f90..e6e119a63d 100644 --- a/core/src/com/unciv/models/gamebasics/Building.java +++ b/core/src/com/unciv/models/gamebasics/Building.java @@ -15,18 +15,20 @@ public class Building extends NamedStats implements ICivilopedia { public int cost; public int maintainance = 0; public FullStats percentStatBonus = new FullStats(); - //public Func GetFlatBonusStats; + public int hurryCostModifier; // Extra cost percentage when purchasing public boolean isWonder = false; public boolean resourceBoostingBuilding = false; public String requiredBuilding; public String requiredBuildingInAllCities; public String requiredResource; + public String cannotBeBuiltWith; // Uniques public String providesFreeBuilding; public int freeTechs; public String unique; // for wonders which have individual functions that are totally unique + /** * The bonus stats that a resource gets when this building is built */ @@ -54,6 +56,10 @@ public class Building extends NamedStats implements ICivilopedia { stringBuilder.append(description + "\r\n" + stats); return stringBuilder.toString(); } + + public int getGoldCost(){ + return (int)( Math.pow(30 * cost,0.75) * (1 + hurryCostModifier/100) / 10 ) * 10; + } }