Split WorldScreen functionality into components - civ stats table, tile info table, tile map holder, notificaations scroll, idle unit button

Added yield on tiles
This commit is contained in:
Yair Morgenstern 2018-01-31 22:45:21 +02:00
parent 561fd417ed
commit 7cbddd883b
17 changed files with 990 additions and 807 deletions

View File

@ -21,8 +21,8 @@ android {
applicationId "com.unciv.game"
minSdkVersion 9
targetSdkVersion 25
versionCode 21
versionName "1.1.2"
versionCode 22
versionName "1.1.3"
}
buildTypes {
release {

View File

@ -2,13 +2,11 @@ package com.unciv.logic.civilization;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Predicate;
import com.sun.jmx.remote.security.NotificationAccessController;
import com.unciv.logic.city.CityInfo;
import com.unciv.logic.map.RoadStatus;
import com.unciv.logic.map.TileInfo;
import com.unciv.logic.map.TileMap;
import com.unciv.ui.UnCivGame;
import com.unciv.ui.pickerscreens.PolicyPickerScreen;
import com.unciv.models.linq.Linq;
import com.unciv.models.linq.LinqCounter;
import com.unciv.models.gamebasics.Building;

View File

@ -1,5 +1,7 @@
package com.unciv.models.stats;
import java.util.HashMap;
public class FullStats extends CivStats // also used for hex stats, since it's basically the same
{
public float production = 0;
@ -60,5 +62,15 @@ public class FullStats extends CivStats // also used for hex stats, since it's b
return valuableParts.toString();
}
public HashMap<String,Integer> toDict(){
HashMap<String,Integer> dict = new HashMap<String, Integer>();
dict.put("Production", (int) production);
dict.put("Food", (int) food);
dict.put("Gold", (int) gold);
dict.put("Science", (int) science);
dict.put("Culture", (int) culture);
return dict;
}
}

View File

@ -18,6 +18,7 @@ import com.unciv.logic.city.CityInfo;
import com.unciv.logic.civilization.CivilizationInfo;
import com.unciv.logic.city.IConstruction;
import com.unciv.logic.map.TileInfo;
import com.unciv.ui.tilegroups.TileGroup;
import com.unciv.ui.utils.CameraStageBaseScreen;
import com.unciv.ui.utils.HexMath;
import com.unciv.models.linq.Linq;
@ -56,7 +57,7 @@ public class CityScreen extends CameraStageBaseScreen {
Table BuildingsTableContainer = new Table();
BuildingsTableContainer.pad(20);
BuildingsTableContainer.setBackground(tileTableBackground);
BuildingsTableContainer.add(new Label("Buildings",skin)).row();
//BuildingsTableContainer.add(new Label("Buildings",skin)).row();
updateBuildingsTable();
ScrollPane buildingsScroll = new ScrollPane(BuildingsTable);
BuildingsTableContainer.add(buildingsScroll).height(stage.getHeight()/2);
@ -137,7 +138,6 @@ public class CityScreen extends CameraStageBaseScreen {
private void updateBuildingsTable(){
BuildingsTable.clear();
Linq<Building> Wonders = new Linq<Building>();
Linq<Building> SpecialistBuildings = new Linq<Building>();
Linq<Building> Others = new Linq<Building>();
@ -255,7 +255,7 @@ public class CityScreen extends CameraStageBaseScreen {
@Override
public void clicked(InputEvent event, float x, float y) {
game.setWorldScreen();
game.worldScreen.setCenterPosition(getCity().cityLocation);
game.worldScreen.tileMapHolder.setCenterPosition(getCity().cityLocation);
dispose();
}
});
@ -270,7 +270,7 @@ public class CityScreen extends CameraStageBaseScreen {
Group allTiles = new Group();
for(final TileInfo tileInfo : game.civInfo.tileMap.getTilesInDistance(cityInfo.cityLocation,5)){
TileGroup group = new TileGroup(tileInfo);
TileGroup group = new TileGroup(cityInfo, tileInfo);
group.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
@ -280,8 +280,10 @@ public class CityScreen extends CameraStageBaseScreen {
});
if(!cityInfo.getTilesInRange().contains(tileInfo) ||
(tileInfo.workingCity!=null && !tileInfo.workingCity.equals(cityInfo.name)))
group.setColor(0,0,0,0.3f);
(tileInfo.workingCity!=null && !tileInfo.workingCity.equals(cityInfo.name))) {
group.setColor(0, 0, 0, 0.3f);
group.yield.setVisible(false);
}
else if(!tileInfo.isCityCenter()) {
group.addPopulationIcon();
group.populationImage.addListener(new ClickListener() {
@ -307,7 +309,6 @@ public class CityScreen extends CameraStageBaseScreen {
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;
@ -320,7 +321,6 @@ public class CityScreen extends CameraStageBaseScreen {
}
float scale = (float) Math.sqrt(distance/initialDistance)* lastScale;
scrollPane.setScale(scale);
game.settings.tilesZoom=scale;
}
@Override

View File

@ -2,8 +2,8 @@ package com.unciv.ui;
public class GameSettings{
public float labelScale = 1.5f;
float buttonScale = 0.9f;
float tilesZoom = 1;
public float buttonScale = 0.9f;
public float tilesZoom = 1;
float cityTilesX =0;
float cityTilesY =0;
float worldScrollX=0;

View File

@ -4,7 +4,6 @@ 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.logic.city.CityInfo;
import com.unciv.logic.civilization.CivilizationInfo;
import com.unciv.models.gamebasics.Unit;
import com.unciv.models.linq.Linq;
@ -28,23 +27,20 @@ public class UnCivGame extends Game {
public CivilizationInfo civInfo;
public GameSettings settings = new GameSettings();
public WorldScreen worldScreen;
public com.unciv.ui.worldscreen.WorldScreen worldScreen;
public void create() {
SetupGameBasics();
Current = this;
if(GameSaver.GetSave("Autosave").exists()) {
try {
GameSaver.LoadGame(this, "Autosave");
for (CityInfo city : this.civInfo.cities) {
if(city.cityStats == null) city.cityStats.update();
}
} catch(Exception ex){ // silent fail if we can't read the autosave
startNewGame();
}
}
else startNewGame();
worldScreen = new WorldScreen();
worldScreen = new com.unciv.ui.worldscreen.WorldScreen();
setWorldScreen();
}
@ -53,7 +49,7 @@ public class UnCivGame extends Game {
civInfo.tileMap.placeUnitNearTile(Vector2.Zero,"Settler");
civInfo.tileMap.placeUnitNearTile(Vector2.Zero,"Scout");
worldScreen = new WorldScreen();
worldScreen = new com.unciv.ui.worldscreen.WorldScreen();
setWorldScreen();
}

View File

@ -1,742 +0,0 @@
package com.unciv.ui;
import com.badlogic.gdx.graphics.Color;
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.logic.civilization.Notification;
import com.unciv.logic.map.TileInfo;
import com.unciv.ui.pickerscreens.PolicyPickerScreen;
import com.unciv.ui.pickerscreens.TechPickerScreen;
import com.unciv.ui.utils.CameraStageBaseScreen;
import com.unciv.ui.utils.GameSaver;
import com.unciv.ui.utils.HexMath;
import com.unciv.ui.utils.ImageGetter;
import com.unciv.models.linq.Linq;
import com.unciv.models.linq.LinqHashMap;
import com.unciv.models.gamebasics.Building;
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, com.unciv.ui.WorldTileGroup> tileGroups = new LinqHashMap<String, com.unciv.ui.WorldTileGroup>();
Table optionsTable = new Table();
Table notificationsTable = new Table();
ScrollPane notificationsScroll = new ScrollPane(notificationsTable);
TextButton selectIdleUnitButton;
public WorldScreen() {
new Label("", skin).getStyle().font.getData().setScale(game.settings.labelScale);
addTiles();
stage.addActor(tileTable);
Drawable tileTableBackground = ImageGetter.getDrawable("skin/tileTableBackground.png")
.tint(new Color(0x004085bf));
tileTableBackground.setMinHeight(0);
tileTableBackground.setMinWidth(0);
tileTable.setBackground(tileTableBackground);
optionsTable.setBackground(tileTableBackground);
//notificationsTable.background(ImageGetter.getSingleColorDrawable(new Color(0x004085bf)));
TextureRegionDrawable civBackground = ImageGetter.getDrawable("skin/civTableBackground.png");
civTable.setBackground(civBackground.tint(new Color(0x004085bf)));
stage.addActor(civTable);
stage.addActor(techButton);
stage.addActor(notificationsScroll);
addSelectIdleUnitButton();
update();
setCenterPosition(Vector2.Zero);
createNextTurnButton(); // needs civ table to be positioned
addOptionsTable();
Linq<String> beginningTutorial = new Linq<String>();
beginningTutorial.add("Hello, and welcome to Unciv!" +
"\r\nCivilization games can be complex, so we'll" +
"\r\n be guiding you along your first journey." +
"\r\nBefore we begin, let's review some basic game concepts.");
beginningTutorial.add("This is the world map, which is made up of multiple tiles." +
"\r\nEach tile can contain units, as well as resources" +
"\r\n and improvements, which we'll get to later");
beginningTutorial.add("You start out with two units -" +
"\r\n a Settler - who can found a city," +
"\r\n and a scout, for exploring the area." +
"\r\n Click on a tile to assign orders the unit!");
displayTutorials("NewGame",beginningTutorial);
}
private void addSelectIdleUnitButton() {
selectIdleUnitButton = new TextButton("Select next idle unit", skin);
selectIdleUnitButton.setPosition(stage.getWidth() / 2 - selectIdleUnitButton.getWidth() / 2, 5);
stage.addActor(selectIdleUnitButton);
selectIdleUnitButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Linq<TileInfo> tilesWithIdleUnits = game.civInfo.tileMap.values().where(new Predicate<TileInfo>() {
@Override
public boolean evaluate(TileInfo arg0) {
return arg0.hasIdleUnit();
}
});
TileInfo tileToSelect;
if (!tilesWithIdleUnits.contains(selectedTile))
tileToSelect = tilesWithIdleUnits.get(0);
else {
int index = tilesWithIdleUnits.indexOf(selectedTile) + 1;
if (tilesWithIdleUnits.size() == index) index = 0;
tileToSelect = tilesWithIdleUnits.get(index);
}
setCenterPosition(tileToSelect.position);
selectedTile = tileToSelect;
update();
}
});
}
void updateIdleUnitButton() {
if (game.civInfo.tileMap.values().any(new Predicate<TileInfo>() {
@Override
public boolean evaluate(TileInfo arg0) {
return arg0.hasIdleUnit();
}
})) {
selectIdleUnitButton.setColor(Color.WHITE);
selectIdleUnitButton.setTouchable(Touchable.enabled);
} else {
selectIdleUnitButton.setColor(Color.GRAY);
selectIdleUnitButton.setTouchable(Touchable.disabled);
}
}
private void updateNotificationsList() {
notificationsTable.clearChildren();
for (final Notification notification : game.civInfo.notifications) {
Label label = new Label(notification.text, skin);
label.setColor(Color.WHITE);
label.setFontScale(1.2f);
Table minitable = new Table();
minitable.background(ImageGetter.getDrawable("skin/civTableBackground.png")
.tint(new Color(0x004085bf)));
minitable.add(label).pad(5);
if(notification.location!=null){
minitable.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
setCenterPosition(notification.location);
}
});
}
notificationsTable.add(minitable).pad(5);
notificationsTable.row();
}
notificationsTable.pack();
notificationsScroll.setSize(stage.getWidth() / 3,
Math.min(notificationsTable.getHeight(),stage.getHeight() / 3));
}
public void update() {
if(game.civInfo.tutorial.contains("CityEntered")){
Linq<String> tutorial = new Linq<String>();
tutorial.add("Once you've done everything you can, " +
"\r\nclick the next turn button on the top right to continue.");
tutorial.add("Each turn, science, culture and gold are added" +
"\r\n to your civilization, your cities' construction" +
"\r\n continues, and they may grow in population or area.");
displayTutorials("NextTurn",tutorial);
}
updateTechButton();
updateTileTable();
updateTiles();
updateCivTable();
updateNotificationsList();
updateIdleUnitButton();
if (game.civInfo.tech.freeTechs != 0) {
game.setScreen(new TechPickerScreen(true));
}
else if(game.civInfo.policies.shouldOpenPolicyPicker){
game.setScreen(new PolicyPickerScreen());
game.civInfo.policies.shouldOpenPolicyPicker=false;
}
}
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());
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 OpenScienceVictoryScreen = new TextButton("Science victory status", skin);
OpenScienceVictoryScreen.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen(new com.unciv.ui.ScienceVictoryScreen());
}
});
optionsTable.add(OpenScienceVictoryScreen).pad(10);
optionsTable.row();
TextButton OpenPolicyPickerScreen = new TextButton("Social Policies", skin);
OpenPolicyPickerScreen.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen(new PolicyPickerScreen());
}
});
optionsTable.add(OpenPolicyPickerScreen).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.pack(); // Needed to show the background.
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());
}
});
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(15);
TextButton CivilopediaButton = new TextButton("Menu", skin);
CivilopediaButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
optionsTable.setVisible(!optionsTable.isVisible());
}
});
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: " + Math.round(game.civInfo.gold)
+ "(" + (nextTurnStats.gold > 0 ? "+" : "") + Math.round(nextTurnStats.gold) + ")", skin));
Label scienceLabel = new Label("Science: +" + Math.round(nextTurnStats.science)
+ "\r\n" + game.civInfo.tech.getAmountResearchedText(), skin);
scienceLabel.setAlignment(Align.center);
civTable.add(scienceLabel);
String happinessText = "Happiness: " + Math.round(game.civInfo.getHappinessForNextTurn());
if (game.civInfo.goldenAges.isGoldenAge())
happinessText += "\r\n GOLDEN AGE (" + game.civInfo.goldenAges.turnsLeftForCurrentGoldenAge + ")";
else
happinessText += "\r\n (" + game.civInfo.goldenAges.storedHappiness + "/" + game.civInfo.goldenAges.happinessRequiredForNextGoldenAge() + ")";
Label happinessLabel = new Label(happinessText, skin);
happinessLabel.setAlignment(Align.center);
civTable.add(happinessLabel);
String cultureString = "Culture: " + "+" + Math.round(nextTurnStats.culture) + "\r\n"
+ "(" + game.civInfo.policies.storedCulture + "/" + game.civInfo.policies.getCultureNeededForNextPolicy() + ")";
Label cultureLabel = new Label(cultureString, skin);
cultureLabel.setAlignment(Align.center);
civTable.add(cultureLabel);
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());
return;
}
game.civInfo.nextTurn();
unitTile = null;
GameSaver.SaveGame(game, "Autosave");
update();
Linq<String> tutorial = new Linq<String>();
tutorial.add("In your first couple of turns," +
"\r\n you will have very little options," +
"\r\n but as your civilization grows, so do the " +
"\r\n number of things requiring your attention");
displayTutorials("NextTurn",tutorial);
}
});
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 com.unciv.ui.WorldTileGroup group = new com.unciv.ui.WorldTileGroup(tileInfo);
group.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Linq<String> tutorial = new Linq<String>();
tutorial.add("Clicking on a tile selects that tile," +
"\r\n and displays information on that tile on the bottom-right," +
"\r\n as well as unit actions, if the tile contains a unit");
displayTutorials("TileClicked",tutorial);
selectedTile = tileInfo;
if (unitTile != null && group.tileInfo.unit == null) {
LinqHashMap<TileInfo, Float> distanceToTiles = game.civInfo.tileMap.getDistanceToTilesWithinTurn(unitTile.position, unitTile.unit.currentMovement);
if (distanceToTiles.containsKey(selectedTile)) {
unitTile.moveUnitToTile(group.tileInfo, distanceToTiles.get(selectedTile));
} else {
unitTile.unit.action = "moveTo " + ((int) selectedTile.position.x) + "," + ((int) selectedTile.position.y);
unitTile.unit.doPreTurnAction(unitTile);
}
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 (com.unciv.ui.TileGroup group : tileGroups.linqValues()) {
group.moveBy(-bottomX+50, -bottomY+50);
}
// 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(100 + topX - bottomX, 100 + 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;
if (scale < 1) return;
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();
if (selectedTile.explored) {
tileTable.add(new Label(selectedTile.toString(), skin)).colspan(2);
tileTable.row();
HashMap<String, Float> TileStatsValues = new HashMap<String, Float>();
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) == 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(Math.round(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 (com.unciv.ui.TileGroup TG : tileGroups.linqValues()) TG.setColor(0, 0, 0, 0.3f);
for (TileInfo tile : game.civInfo.tileMap.getDistanceToTilesWithinTurn(unitTile.position, unitTile.unit.currentMovement).keySet()) {
tileGroups.get(tile.position.toString()).setColor(Color.WHITE);
}
update();
}
});
tileTable.add(moveUnitButton).colspan(2)
.size(moveUnitButton.getWidth() * buttonScale, moveUnitButton.getHeight() * buttonScale);
if (selectedTile.unit.name.equals("Settler")) {
addUnitAction(tileTable, "Found City",
!game.civInfo.tileMap.getTilesInDistance(selectedTile.position, 2).any(new Predicate<TileInfo>() {
@Override
public boolean evaluate(TileInfo arg0) {
return arg0.isCityCenter();
}
}),
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Linq<String> tutorial = new Linq<String>();
tutorial.add("You have founded a city!" +
"\r\nCities are the lifeblood of your empire," +
"\r\n providing gold and science empire-wide," +
"\r\n which are displayed on the top bar.");
tutorial.add("Science is used to research technologies." +
"\r\nYou can enter the technology screen by clicking" +
"\r\n on the button on the top-left, underneath the bar");
tutorial.add("You can click the city name to enter" +
"\r\n the city screen to assign population," +
"\r\n choose production, and see information on the city");
displayTutorials("CityFounded",tutorial);
game.civInfo.addCity(selectedTile.position);
if (unitTile == selectedTile)
unitTile = null; // The settler was in the middle of moving and we then founded a city with it
selectedTile.unit = null; // Remove settler!
update();
}
});
}
if (selectedTile.unit.name.equals("Worker")) {
String improvementButtonText = selectedTile.improvementInProgress == null ?
"Construct\r\nimprovement" : selectedTile.improvementInProgress + "\r\nin progress";
addUnitAction(tileTable, improvementButtonText, !selectedTile.isCityCenter() ||
GameBasics.TileImprovements.linqValues().any(new Predicate<TileImprovement>() {
@Override
public boolean evaluate(TileImprovement arg0) {
return selectedTile.canBuildImprovement(arg0);
}
})
, new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen(new com.unciv.ui.pickerscreens.ImprovementPickerScreen(selectedTile));
}
});
addUnitAction(tileTable, "automation".equals(selectedTile.unit.action) ? "Stop automation" : "Automate", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
if ("automation".equals(selectedTile.unit.action))
selectedTile.unit.action = null;
else {
selectedTile.unit.action = "automation";
selectedTile.unit.doAutomatedAction(selectedTile);
}
update();
}
});
}
if (selectedTile.unit.name.equals("Great Scientist")) {
addUnitAction(tileTable, "Discover Technology", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.civInfo.tech.freeTechs += 1;
selectedTile.unit = null;// destroy!
game.setScreen(new TechPickerScreen(true));
}
});
addUnitAction(tileTable, "Construct Academy", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.improvement = "Academy";
selectedTile.unit = null;// destroy!
update();
}
});
}
if (selectedTile.unit.name.equals("Great Artist")) {
addUnitAction(tileTable, "Start Golden Age", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.civInfo.goldenAges.enterGoldenAge();
selectedTile.unit = null;// destroy!
update();
}
});
addUnitAction(tileTable, "Construct Landmark", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.improvement = "Landmark";
selectedTile.unit = null;// destroy!
update();
}
});
}
if (selectedTile.unit.name.equals("Great Engineer")) {
addUnitAction(tileTable, "Hurry Wonder", selectedTile.isCityCenter() &&
selectedTile.getCity().cityConstructions.getCurrentConstruction() instanceof Building &&
((Building) selectedTile.getCity().cityConstructions.getCurrentConstruction()).isWonder,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.getCity().cityConstructions.addConstruction(300 + (30 * selectedTile.getCity().population.population)); //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
selectedTile.unit = null; // destroy!
update();
}
});
addUnitAction(tileTable, "Construct Manufactory", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.improvement = "Manufactory";
selectedTile.unit = null;// destroy!
update();
}
});
}
if (selectedTile.unit.name.equals("Great Merchant")) {
addUnitAction(tileTable, "Conduct Trade Mission", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.civInfo.gold += 350; // + 50 * era_number - todo!
selectedTile.unit = null; // destroy!
update();
}
});
addUnitAction(tileTable, "Construct Customs House", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.improvement = "Customs House";
selectedTile.unit = null;// destroy!
update();
}
});
}
}
tileTable.pack();
tileTable.setPosition(stage.getWidth() - 10 - tileTable.getWidth(), 10);
}
private void addUnitAction(Table tileTable, String actionText, boolean canAct, ClickListener action) {
TextButton actionButton = new TextButton(actionText, skin);
actionButton.getLabel().setFontScale(buttonScale);
actionButton.addListener(action);
if (selectedTile.unit.currentMovement == 0 || !canAct) {
actionButton.setColor(Color.GRAY);
actionButton.setTouchable(Touchable.disabled);
}
tileTable.row();
tileTable.add(actionButton).colspan(2)
.size(actionButton.getWidth() * buttonScale, actionButton.getHeight() * buttonScale);
}
private void updateTiles() {
for (com.unciv.ui.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 (com.unciv.ui.WorldTileGroup WG : tileGroups.linqValues()) WG.setIsViewable(false);
HashSet<String> ViewableVectorStrings = new HashSet<String>();
// 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))
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 (TileInfo tileInfo : game.civInfo.tileMap.getViewableTiles(tile.position,2))
ViewableVectorStrings.add(tileInfo.position.toString());
for (String string : ViewableVectorStrings)
if (tileGroups.containsKey(string))
tileGroups.get(string).setIsViewable(true);
}
void setCenterPosition(final Vector2 vector) {
com.unciv.ui.TileGroup TG = tileGroups.linqValues().first(new Predicate<com.unciv.ui.WorldTileGroup>() {
@Override
public boolean evaluate(com.unciv.ui.WorldTileGroup arg0) {
return arg0.tileInfo.position.equals(vector);
}
});
scrollPane.layout(); // Fit the scroll pane to the contents - otherwise, setScroll won't work!
// We want to center on the middle of TG (TG.getX()+TG.getWidth()/2)
// and so the scroll position (== where the screen starts) needs to be half a screen away
scrollPane.setScrollX(TG.getX() + TG.getWidth() / 2 - stage.getWidth() / 2);
// Here it's the same, only the Y axis is inverted - when at 0 we're at the top, not bottom - so we invert it back.
scrollPane.setScrollY(scrollPane.getMaxY() - (TG.getY() + TG.getWidth() / 2 - stage.getHeight() / 2));
scrollPane.updateVisualScroll();
}
@Override
public void resize(int width, int height) {
if(stage.getViewport().getScreenWidth()!=width || stage.getViewport().getScreenHeight()!=height) {
super.resize(width, height);
game.worldScreen = new WorldScreen(); // start over.
game.setWorldScreen();
}
}
}

View File

@ -0,0 +1,54 @@
package com.unciv.ui;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Stack;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.unciv.models.stats.FullStats;
import com.unciv.ui.utils.CameraStageBaseScreen;
import com.unciv.ui.utils.ImageGetter;
import java.util.HashMap;
public class YieldGroup extends HorizontalGroup {
public void setStats(FullStats stats) {
clearChildren();
HashMap<String,Integer> dict = stats.toDict();
for(String key : dict.keySet()){
int value = dict.get(key);
if(value >0) addActor(getStatTable(key,value));
}
pack();
}
Table getStatTable(String statName, int number){
Table table = new Table();
if(number==1){
table.add(ImageGetter.getStatIcon(statName));
}
else if(number==2){
table.add(ImageGetter.getStatIcon(statName)).row();
table.add(ImageGetter.getStatIcon(statName));
}
else if(number==3){
table.add(ImageGetter.getStatIcon(statName)).colspan(2).row();
table.add(ImageGetter.getStatIcon(statName));
table.add(ImageGetter.getStatIcon(statName));
}
else if(number==4){
table.add(ImageGetter.getStatIcon(statName));
table.add(ImageGetter.getStatIcon(statName)).row();
table.add(ImageGetter.getStatIcon(statName));
table.add(ImageGetter.getStatIcon(statName));
}
else{
Image largeImage = ImageGetter.getStatIcon(statName);
table.add(largeImage).size(largeImage.getWidth()*1.5f, largeImage.getHeight()*1.5f);
}
table.pack();
return table;
}
}

View File

@ -1,4 +1,4 @@
package com.unciv.ui;
package com.unciv.ui.tilegroups;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
@ -6,74 +6,87 @@ 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.logic.city.CityInfo;
import com.unciv.logic.map.RoadStatus;
import com.unciv.logic.map.TileInfo;
import com.unciv.models.linq.LinqHashMap;
import com.unciv.ui.YieldGroup;
import com.unciv.ui.utils.HexMath;
import com.unciv.ui.utils.ImageGetter;
public class TileGroup extends Group {
Image terrainImage;
protected Image terrainImage;
String terrainType;
Image resourceImage;
Image unitImage;
Image improvementImage;
public YieldGroup yield = new YieldGroup();
String improvementType;
Image populationImage;
public Image populationImage;
LinqHashMap<String,Image> roadImages = new LinqHashMap<String, Image>();
Image hexagon;
protected Image hexagon;
private CityInfo city;
Container<TextButton> cityButton;
TileInfo tileInfo;
protected Container<TextButton> cityButton;
public TileInfo tileInfo;
TileGroup(TileInfo tileInfo){
public TileGroup(CityInfo city, TileInfo tileInfo){
this.city = city;
this.tileInfo = tileInfo;
terrainType = tileInfo.getLastTerrain().name;
String terrainFileName = "TerrainIcons/" + terrainType.replace(' ','_') + "_(Civ5).png";
terrainImage = com.unciv.ui.utils.ImageGetter.getImage(terrainFileName);
terrainImage.setSize(50,50);
terrainImage = ImageGetter.getImage(terrainFileName);
int groupSize = 50;
terrainImage.setSize(groupSize,groupSize);
setSize(groupSize,groupSize);
addActor(terrainImage);
addActor(yield);
if(city==null) yield.setColor(1,1,1,0.4f);
}
void addPopulationIcon(){
populationImage = com.unciv.ui.utils.ImageGetter.getImage("StatIcons/populationGreen.png");
public void addPopulationIcon(){
populationImage = ImageGetter.getImage("StatIcons/populationGreen.png");
populationImage.setSize(20,20);
populationImage.moveBy(0, terrainImage.getHeight()-populationImage.getHeight()); // top left
addActor(populationImage);
}
void removePopulationIcon(){
protected void removePopulationIcon(){
populationImage.remove();
populationImage = null;
}
void update() {
if(tileInfo.explored){
public void update() {
if (tileInfo.explored) {
terrainImage.setColor(Color.WHITE);
}
else{
} else {
terrainImage.setColor(Color.BLACK);
return;
}
if(!terrainType.equals(tileInfo.getLastTerrain().name)) {
if (!terrainType.equals(tileInfo.getLastTerrain().name)) {
terrainType = tileInfo.getLastTerrain().name;
String terrainFileName = "TerrainIcons/" + terrainType.replace(' ', '_') + "_(Civ5).png";
terrainImage.setDrawable(com.unciv.ui.utils.ImageGetter.getDrawable(terrainFileName)); // In case we e.g. removed a jungle
terrainImage.setDrawable(ImageGetter.getDrawable(terrainFileName)); // In case we e.g. removed a jungle
}
if (tileInfo.explored && tileInfo.hasViewableResource() && resourceImage == null) { // Need to add the resource image!
if (tileInfo.hasViewableResource() && resourceImage == null) { // Need to add the resource image!
String fileName = "ResourceIcons/" + tileInfo.resource + "_(Civ5).png";
Image image = com.unciv.ui.utils.ImageGetter.getImage(fileName);
image.setSize(20,20);
image.moveBy(terrainImage.getWidth()-image.getWidth(), 0); // bottom right
Image image = ImageGetter.getImage(fileName);
image.setSize(20, 20);
image.moveBy(terrainImage.getWidth() - image.getWidth(), 0); // bottom right
resourceImage = image;
if (city != null) image.setColor(1, 1, 1, 0.5f);
addActor(image);
}
if (tileInfo.explored && tileInfo.unit != null && unitImage == null) {
unitImage = com.unciv.ui.utils.ImageGetter.getImage("UnitIcons/" + tileInfo.unit.name.replace(" ","_") + "_(Civ5).png");
if (tileInfo.unit != null && unitImage == null) {
unitImage = ImageGetter.getImage("UnitIcons/" + tileInfo.unit.name.replace(" ", "_") + "_(Civ5).png");
addActor(unitImage);
if (city != null) unitImage.setColor(1, 1, 1, 0.5f);
unitImage.setSize(20, 20); // not moved - is at bottom left
}
@ -82,35 +95,36 @@ public class TileGroup extends Group {
unitImage = null;
}
if(unitImage!=null){
if(!tileInfo.hasIdleUnit()) unitImage.setColor(Color.GRAY);
if (unitImage != null) {
if (!tileInfo.hasIdleUnit()) unitImage.setColor(Color.GRAY);
else unitImage.setColor(Color.WHITE);
}
if (tileInfo.explored && tileInfo.improvement != null &&!tileInfo.improvement.equals(improvementType)) {
improvementImage = com.unciv.ui.utils.ImageGetter.getImage("ImprovementIcons/" + tileInfo.improvement.replace(' ','_') + "_(Civ5).png");
if (tileInfo.improvement != null && !tileInfo.improvement.equals(improvementType)) {
improvementImage = ImageGetter.getImage("ImprovementIcons/" + tileInfo.improvement.replace(' ', '_') + "_(Civ5).png");
if (city != null) improvementImage.setColor(1, 1, 1, 0.5f);
addActor(improvementImage);
improvementImage.setSize(20, 20);
improvementImage.moveBy(terrainImage.getWidth()-improvementImage.getWidth(),
improvementImage.moveBy(terrainImage.getWidth() - improvementImage.getWidth(),
terrainImage.getHeight() - improvementImage.getHeight()); // top right
improvementType = tileInfo.improvement;
}
if(populationImage!=null){
if(tileInfo.workingCity !=null) populationImage.setColor(Color.WHITE);
if (populationImage != null) {
if (tileInfo.workingCity != null) populationImage.setColor(Color.WHITE);
else populationImage.setColor(Color.GRAY);
}
if(tileInfo.roadStatus != RoadStatus.None){
if (tileInfo.roadStatus != RoadStatus.None) {
for (TileInfo neighbor : tileInfo.getNeighbors()) {
if (neighbor.roadStatus == RoadStatus.None) continue;
if (!roadImages.containsKey(neighbor.position.toString())) {
Image image = com.unciv.ui.utils.ImageGetter.getImage(com.unciv.ui.utils.ImageGetter.WhiteDot);
Image image = ImageGetter.getImage(ImageGetter.WhiteDot);
roadImages.put(neighbor.position.toString(), image);
Vector2 relativeHexPosition = tileInfo.position.cpy().sub(neighbor.position);
Vector2 relativeWorldPosition = com.unciv.ui.utils.HexMath.Hex2WorldCoords(relativeHexPosition);
Vector2 relativeWorldPosition = HexMath.Hex2WorldCoords(relativeHexPosition);
// This is some crazy voodoo magic so I'll explain.
image.moveBy(25, 25); // Move road to center of tile
@ -123,10 +137,17 @@ public class TileGroup extends Group {
image.setRotation((float) (180 / Math.PI * Math.atan2(relativeWorldPosition.y, relativeWorldPosition.x)));
}
if(tileInfo.roadStatus == RoadStatus.Railroad && neighbor.roadStatus == RoadStatus.Railroad)
if (tileInfo.roadStatus == RoadStatus.Railroad && neighbor.roadStatus == RoadStatus.Railroad)
roadImages.get(neighbor.position.toString()).setColor(Color.GRAY); // railroad
else roadImages.get(neighbor.position.toString()).setColor(Color.BROWN); // road
}
}
yield.setStats(tileInfo.getTileStats(city));
yield.setOrigin(Align.center);
yield.setScale(0.7f);
yield.setPosition(getWidth() / 2 - yield.getWidth() / 2, getHeight() / 2 - yield.getHeight() / 2);
}
}

View File

@ -1,4 +1,4 @@
package com.unciv.ui;
package com.unciv.ui.tilegroups;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.Container;
@ -6,17 +6,21 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.unciv.logic.city.CityInfo;
import com.unciv.logic.map.TileInfo;
import com.unciv.ui.CityScreen;
import com.unciv.ui.UnCivGame;
import com.unciv.ui.utils.ImageGetter;
import com.unciv.ui.worldscreen.WorldScreen;
public class WorldTileGroup extends TileGroup {
WorldTileGroup(TileInfo tileInfo) {
super(tileInfo);
public WorldTileGroup(TileInfo tileInfo) {
super(null, tileInfo);
}
void setIsViewable(boolean isViewable) {
public void setIsViewable(boolean isViewable) {
if (isViewable) {
setColor(1, 1, 0, 1); // Only alpha really changes anything
setColor(0, 0, 0, 1); // Only alpha really changes anything
tileInfo.explored=true;
update();
}
@ -24,7 +28,7 @@ public class WorldTileGroup extends TileGroup {
}
void update(WorldScreen worldScreen) {
public void update(WorldScreen worldScreen) {
super.update();
if(tileInfo.workingCity != null && populationImage==null) addPopulationIcon();
@ -32,7 +36,7 @@ public class WorldTileGroup extends TileGroup {
if (tileInfo.owner != null && hexagon == null) {
hexagon = com.unciv.ui.utils.ImageGetter.getImage("TerrainIcons/Hexagon.png");
hexagon = ImageGetter.getImage("TerrainIcons/Hexagon.png");
float imageScale = terrainImage.getWidth() * 1.3f / hexagon.getWidth();
hexagon.setScale(imageScale);
hexagon.setPosition((getWidth() - hexagon.getWidth() * imageScale) / 2,

View File

@ -22,7 +22,7 @@ public class CameraStageBaseScreen implements Screen {
public com.unciv.ui.UnCivGame game;
public Stage stage;
public Skin skin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
public static Skin skin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json"));
static Batch batch = new SpriteBatch();
public CameraStageBaseScreen() {

View File

@ -0,0 +1,74 @@
package com.unciv.ui.worldscreen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
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.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.unciv.logic.civilization.CivilizationInfo;
import com.unciv.models.stats.CivStats;
import com.unciv.ui.utils.ImageGetter;
public class CivStatsTable extends Table {
CivStatsTable(){
TextureRegionDrawable civBackground = ImageGetter.getDrawable("skin/civTableBackground.png");
setBackground(civBackground.tint(new Color(0x004085bf)));
}
void update(final WorldScreen screen) {
CivilizationInfo civInfo = screen.game.civInfo;
Skin skin = screen.skin;
clear();
row().pad(15);
TextButton CivilopediaButton = new TextButton("Menu", skin);
CivilopediaButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
screen.optionsTable.setVisible(!screen.optionsTable.isVisible());
}
});
CivilopediaButton.getLabel().setFontScale(screen.buttonScale);
add(CivilopediaButton)
.size(CivilopediaButton.getWidth() * screen.buttonScale, CivilopediaButton.getHeight() * screen.buttonScale);
add(new Label("Turns: " + civInfo.turns + "/400", skin));
CivStats nextTurnStats = civInfo.getStatsForNextTurn();
add(new Label("Gold: " + Math.round(civInfo.gold)
+ "(" + (nextTurnStats.gold > 0 ? "+" : "") + Math.round(nextTurnStats.gold) + ")", skin));
Label scienceLabel = new Label("Science: +" + Math.round(nextTurnStats.science)
+ "\r\n" + civInfo.tech.getAmountResearchedText(), skin);
scienceLabel.setAlignment(Align.center);
add(scienceLabel);
String happinessText = "Happiness: " + Math.round(civInfo.getHappinessForNextTurn());
if (civInfo.goldenAges.isGoldenAge())
happinessText += "\r\n GOLDEN AGE (" + civInfo.goldenAges.turnsLeftForCurrentGoldenAge + ")";
else
happinessText += "\r\n (" + civInfo.goldenAges.storedHappiness + "/"
+ civInfo.goldenAges.happinessRequiredForNextGoldenAge() + ")";
Label happinessLabel = new Label(happinessText, skin);
happinessLabel.setAlignment(Align.center);
add(happinessLabel);
String cultureString = "Culture: " + "+" + Math.round(nextTurnStats.culture) + "\r\n"
+ "(" + civInfo.policies.storedCulture + "/" + civInfo.policies.getCultureNeededForNextPolicy() + ")";
Label cultureLabel = new Label(cultureString, skin);
cultureLabel.setAlignment(Align.center);
add(cultureLabel);
pack();
setPosition(10, screen.stage.getHeight() - 10 - getHeight());
setWidth(screen.stage.getWidth() - 20);
}
}

View File

@ -0,0 +1,59 @@
package com.unciv.ui.worldscreen;
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.badlogic.gdx.utils.Predicate;
import com.unciv.logic.map.TileInfo;
import com.unciv.models.linq.Linq;
import com.unciv.ui.utils.CameraStageBaseScreen;
public class IdleUnitButton extends TextButton {
final WorldScreen worldScreen;
IdleUnitButton(final WorldScreen worldScreen) {
super("Select next idle unit", CameraStageBaseScreen.skin);
this.worldScreen = worldScreen;
setPosition(worldScreen.stage.getWidth() / 2 - getWidth() / 2, 5);
addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Linq<TileInfo> tilesWithIdleUnits = worldScreen.game.civInfo.tileMap.values().where(new Predicate<TileInfo>() {
@Override
public boolean evaluate(TileInfo arg0) {
return arg0.hasIdleUnit();
}
});
TileInfo tileToSelect;
if (!tilesWithIdleUnits.contains(worldScreen.tileMapHolder.selectedTile))
tileToSelect = tilesWithIdleUnits.get(0);
else {
int index = tilesWithIdleUnits.indexOf(worldScreen.tileMapHolder.selectedTile) + 1;
if (tilesWithIdleUnits.size() == index) index = 0;
tileToSelect = tilesWithIdleUnits.get(index);
}
worldScreen.tileMapHolder.setCenterPosition(tileToSelect.position);
worldScreen.tileMapHolder.selectedTile = tileToSelect;
worldScreen.update();
}
});
}
void update() {
if (worldScreen.game.civInfo.tileMap.values().any(new Predicate<TileInfo>() {
@Override
public boolean evaluate(TileInfo arg0) {
return arg0.hasIdleUnit();
}
})) {
worldScreen.idleUnitButton.setColor(Color.WHITE);
worldScreen.idleUnitButton.setTouchable(Touchable.enabled);
} else {
worldScreen.idleUnitButton.setColor(Color.GRAY);
worldScreen.idleUnitButton.setTouchable(Touchable.disabled);
}
}
}

View File

@ -0,0 +1,55 @@
package com.unciv.ui.worldscreen;
import com.badlogic.gdx.graphics.Color;
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.Table;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.unciv.logic.civilization.CivilizationInfo;
import com.unciv.logic.civilization.Notification;
import com.unciv.ui.utils.CameraStageBaseScreen;
import com.unciv.ui.utils.ImageGetter;
public class NotificationsScroll extends ScrollPane {
Table notificationsTable = new Table();
final WorldScreen worldScreen;
public NotificationsScroll(WorldScreen worldScreen) {
super(null);
this.worldScreen = worldScreen;
setWidget(notificationsTable);
}
void update() {
notificationsTable.clearChildren();
for (final Notification notification : CivilizationInfo.current().notifications) {
Label label = new Label(notification.text, CameraStageBaseScreen.skin);
label.setColor(Color.WHITE);
label.setFontScale(1.2f);
Table minitable = new Table();
minitable.background(ImageGetter.getDrawable("skin/civTableBackground.png")
.tint(new Color(0x004085bf)));
minitable.add(label).pad(5);
if(notification.location!=null){
minitable.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
worldScreen.tileMapHolder.setCenterPosition(notification.location);
}
});
}
notificationsTable.add(minitable).pad(5);
notificationsTable.row();
}
notificationsTable.pack();
setSize(worldScreen.stage.getWidth() / 3,
Math.min(notificationsTable.getHeight(),worldScreen.stage.getHeight() / 3));
}
}

View File

@ -0,0 +1,268 @@
package com.unciv.ui.worldscreen;
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.Skin;
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.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Predicate;
import com.unciv.logic.map.TileInfo;
import com.unciv.models.gamebasics.Building;
import com.unciv.models.gamebasics.GameBasics;
import com.unciv.models.gamebasics.TileImprovement;
import com.unciv.models.linq.Linq;
import com.unciv.models.stats.FullStats;
import com.unciv.ui.tilegroups.TileGroup;
import com.unciv.ui.pickerscreens.TechPickerScreen;
import com.unciv.ui.utils.ImageGetter;
import java.util.HashMap;
public class TileInfoTable extends Table {
private final WorldScreen worldScreen;
public TileInfoTable(WorldScreen worldScreen){
this.worldScreen = worldScreen;
Drawable tileTableBackground = ImageGetter.getDrawable("skin/tileTableBackground.png")
.tint(new Color(0x004085bf));
tileTableBackground.setMinHeight(0);
tileTableBackground.setMinWidth(0);
setBackground(tileTableBackground);
}
void updateTileTable(final TileInfo selectedTile) {
if (selectedTile == null) return;
clearChildren();
FullStats stats = selectedTile.getTileStats();
pad(20);
columnDefaults(0).padRight(10);
Skin skin = worldScreen.skin;
if (selectedTile.explored) {
add(new Label(selectedTile.toString(), skin)).colspan(2);
row();
HashMap<String, Integer> TileStatsValues = stats.toDict();
for (String key : TileStatsValues.keySet()) {
if (TileStatsValues.get(key) == 0)
continue; // this tile gives nothing of this stat, so why even display it?
add(ImageGetter.getStatIcon(key)).align(Align.right);
add(new Label(TileStatsValues.get(key) + "", skin)).align(Align.left);
row();
}
}
if (selectedTile.unit != null) {
TextButton moveUnitButton = new TextButton("Move to", skin);
if (worldScreen.tileMapHolder.unitTile == selectedTile) moveUnitButton = new TextButton("Stop movement", skin);
moveUnitButton.getLabel().setFontScale(worldScreen.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 (worldScreen.tileMapHolder.unitTile != null) {
worldScreen.tileMapHolder.unitTile = null;
worldScreen.update();
return;
}
worldScreen.tileMapHolder.unitTile = selectedTile;
// Set all tiles transparent except those in unit range
for (TileGroup TG : worldScreen.tileGroups.linqValues()) TG.setColor(0, 0, 0, 0.3f);
for (TileInfo tile : worldScreen.game.civInfo.tileMap.getDistanceToTilesWithinTurn(worldScreen.tileMapHolder.unitTile.position, worldScreen.tileMapHolder.unitTile.unit.currentMovement).keySet()) {
worldScreen.tileGroups.get(tile.position.toString()).setColor(Color.WHITE);
}
worldScreen.update();
}
});
add(moveUnitButton).colspan(2)
.size(moveUnitButton.getWidth() * worldScreen.buttonScale, moveUnitButton.getHeight() * worldScreen.buttonScale);
if (selectedTile.unit.name.equals("Settler")) {
addUnitAction("Found City",
!worldScreen.game.civInfo.tileMap.getTilesInDistance(selectedTile.position, 2).any(new Predicate<TileInfo>() {
@Override
public boolean evaluate(TileInfo arg0) {
return arg0.isCityCenter();
}
}),
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Linq<String> tutorial = new Linq<String>();
tutorial.add("You have founded a city!" +
"\r\nCities are the lifeblood of your empire," +
"\r\n providing gold and science empire-wide," +
"\r\n which are displayed on the top bar.");
tutorial.add("Science is used to research technologies." +
"\r\nYou can enter the technology screen by clicking" +
"\r\n on the button on the top-left, underneath the bar");
tutorial.add("You can click the city name to enter" +
"\r\n the city screen to assign population," +
"\r\n choose production, and see information on the city");
worldScreen.displayTutorials("CityFounded",tutorial);
worldScreen.game.civInfo.addCity(selectedTile.position);
if (worldScreen.tileMapHolder.unitTile == selectedTile)
worldScreen.tileMapHolder.unitTile = null; // The settler was in the middle of moving and we then founded a city with it
selectedTile.unit = null; // Remove settler!
worldScreen.update();
}
});
}
if (selectedTile.unit.name.equals("Worker")) {
String improvementButtonText = selectedTile.improvementInProgress == null ?
"Construct\r\nimprovement" : selectedTile.improvementInProgress + "\r\nin progress";
addUnitAction(improvementButtonText, !selectedTile.isCityCenter() ||
GameBasics.TileImprovements.linqValues().any(new Predicate<TileImprovement>() {
@Override
public boolean evaluate(TileImprovement arg0) {
return selectedTile.canBuildImprovement(arg0);
}
})
, new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
worldScreen.game.setScreen(new com.unciv.ui.pickerscreens.ImprovementPickerScreen(selectedTile));
}
});
addUnitAction("automation".equals(selectedTile.unit.action) ? "Stop automation" : "Automate", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
if ("automation".equals(selectedTile.unit.action))
selectedTile.unit.action = null;
else {
selectedTile.unit.action = "automation";
selectedTile.unit.doAutomatedAction(selectedTile);
}
worldScreen.update();
}
});
}
if (selectedTile.unit.name.equals("Great Scientist")) {
addUnitAction("Discover Technology", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
worldScreen.game.civInfo.tech.freeTechs += 1;
selectedTile.unit = null;// destroy!
worldScreen.game.setScreen(new TechPickerScreen(true));
}
});
addUnitAction("Construct Academy", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.improvement = "Academy";
selectedTile.unit = null;// destroy!
worldScreen.update();
}
});
}
if (selectedTile.unit.name.equals("Great Artist")) {
addUnitAction("Start Golden Age", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
worldScreen.game.civInfo.goldenAges.enterGoldenAge();
selectedTile.unit = null;// destroy!
worldScreen.update();
}
});
addUnitAction("Construct Landmark", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.improvement = "Landmark";
selectedTile.unit = null;// destroy!
worldScreen.update();
}
});
}
if (selectedTile.unit.name.equals("Great Engineer")) {
addUnitAction("Hurry Wonder", selectedTile.isCityCenter() &&
selectedTile.getCity().cityConstructions.getCurrentConstruction() instanceof Building &&
((Building) selectedTile.getCity().cityConstructions.getCurrentConstruction()).isWonder,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.getCity().cityConstructions.addConstruction(300 + (30 * selectedTile.getCity().population.population)); //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
selectedTile.unit = null; // destroy!
worldScreen.update();
}
});
addUnitAction("Construct Manufactory", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.improvement = "Manufactory";
selectedTile.unit = null;// destroy!
worldScreen.update();
}
});
}
if (selectedTile.unit.name.equals("Great Merchant")) {
addUnitAction("Conduct Trade Mission", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
worldScreen.game.civInfo.gold += 350; // + 50 * era_number - todo!
selectedTile.unit = null; // destroy!
worldScreen.update();
}
});
addUnitAction("Construct Customs House", true,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
selectedTile.improvement = "Customs House";
selectedTile.unit = null;// destroy!
worldScreen.update();
}
});
}
}
pack();
setPosition(worldScreen.stage.getWidth() - 10 - getWidth(), 10);
}
private void addUnitAction(String actionText, boolean canAct, ClickListener action) {
TextButton actionButton = new TextButton(actionText, worldScreen.skin);
actionButton.getLabel().setFontScale(worldScreen.buttonScale);
actionButton.addListener(action);
if (worldScreen.tileMapHolder.selectedTile.unit.currentMovement == 0 || !canAct) {
actionButton.setColor(Color.GRAY);
actionButton.setTouchable(Touchable.disabled);
}
row();
add(actionButton).colspan(2)
.size(actionButton.getWidth() * worldScreen.buttonScale, actionButton.getHeight() * worldScreen.buttonScale);
}
}

View File

@ -0,0 +1,168 @@
package com.unciv.ui.worldscreen;
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.ScrollPane;
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.Predicate;
import com.unciv.logic.civilization.CivilizationInfo;
import com.unciv.logic.map.TileInfo;
import com.unciv.models.linq.Linq;
import com.unciv.models.linq.LinqHashMap;
import com.unciv.ui.tilegroups.TileGroup;
import com.unciv.ui.tilegroups.WorldTileGroup;
import com.unciv.ui.utils.HexMath;
import java.util.HashSet;
public class TileMapHolder extends ScrollPane {
final WorldScreen worldScreen;
TileInfo selectedTile = null;
TileInfo unitTile = null;
public TileMapHolder(final WorldScreen worldScreen) {
super(null);
this.worldScreen=worldScreen;
}
void addTiles() {
final Group allTiles = new Group();
float topX = 0;
float topY = 0;
float bottomX = 0;
float bottomY = 0;
for (final TileInfo tileInfo : worldScreen.game.civInfo.tileMap.values()) {
final WorldTileGroup group = new WorldTileGroup(tileInfo);
group.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Linq<String> tutorial = new Linq<String>();
tutorial.add("Clicking on a tile selects that tile," +
"\r\n and displays information on that tile on the bottom-right," +
"\r\n as well as unit actions, if the tile contains a unit");
worldScreen.displayTutorials("TileClicked",tutorial);
selectedTile = tileInfo;
if (unitTile != null && group.tileInfo.unit == null) {
LinqHashMap<TileInfo, Float> distanceToTiles = worldScreen.game.civInfo.tileMap.getDistanceToTilesWithinTurn(unitTile.position, unitTile.unit.currentMovement);
if (distanceToTiles.containsKey(selectedTile)) {
unitTile.moveUnitToTile(group.tileInfo, distanceToTiles.get(selectedTile));
} else {
unitTile.unit.action = "moveTo " + ((int) selectedTile.position.x) + "," + ((int) selectedTile.position.y);
unitTile.unit.doPreTurnAction(unitTile);
}
unitTile = null;
selectedTile = group.tileInfo;
}
worldScreen.update();
}
});
Vector2 positionalVector = HexMath.Hex2WorldCoords(tileInfo.position);
int groupSize = 50;
group.setPosition(worldScreen.stage.getWidth() / 2 + positionalVector.x * 0.8f * groupSize,
worldScreen.stage.getHeight() / 2 + positionalVector.y * 0.8f * groupSize);
worldScreen.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 : worldScreen.tileGroups.linqValues()) {
group.moveBy(-bottomX+50, -bottomY+50);
}
// 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(100 + topX - bottomX, 100 + topY - bottomY);
setWidget(allTiles);
setFillParent(true);
setOrigin(worldScreen.stage.getWidth() / 2, worldScreen.stage.getHeight() / 2);
setSize(worldScreen.stage.getWidth(), worldScreen.stage.getHeight());
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 = getScaleX();
}
float scale = (float) Math.sqrt(distance / initialDistance) * lastScale;
if (scale < 1) return;
setScale(scale);
}
});
}
void updateTiles() {
for (WorldTileGroup WG : worldScreen.tileGroups.linqValues()) WG.update(worldScreen);
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 : worldScreen.tileGroups.linqValues()) WG.setIsViewable(false);
HashSet<String> ViewableVectorStrings = new HashSet<String>();
// tiles adjacent to city tiles
CivilizationInfo civInfo = worldScreen.game.civInfo;
for (TileInfo tileInfo : civInfo.tileMap.values())
if (civInfo.civName.equals(tileInfo.owner))
for (Vector2 adjacentLocation : HexMath.GetAdjacentVectors(tileInfo.position))
ViewableVectorStrings.add(adjacentLocation.toString());
// Tiles within 2 tiles of units
for (TileInfo tile : civInfo.tileMap.values()
.where(new Predicate<TileInfo>() {
@Override
public boolean evaluate(TileInfo arg0) {
return arg0.unit != null;
}
}))
for (TileInfo tileInfo : civInfo.tileMap.getViewableTiles(tile.position,2))
ViewableVectorStrings.add(tileInfo.position.toString());
for (String string : ViewableVectorStrings)
if (worldScreen.tileGroups.containsKey(string))
worldScreen.tileGroups.get(string).setIsViewable(true);
}
public void setCenterPosition(final Vector2 vector) {
TileGroup TG = worldScreen.tileGroups.linqValues().first(new Predicate<WorldTileGroup>() {
@Override
public boolean evaluate(WorldTileGroup arg0) {
return arg0.tileInfo.position.equals(vector);
}
});
layout(); // Fit the scroll pane to the contents - otherwise, setScroll won't work!
// We want to center on the middle of TG (TG.getX()+TG.getWidth()/2)
// and so the scroll position (== where the screen starts) needs to be half a screen away
setScrollX(TG.getX() + TG.getWidth() / 2 - worldScreen.stage.getWidth() / 2);
// Here it's the same, only the Y axis is inverted - when at 0 we're at the top, not bottom - so we invert it back.
setScrollY(getMaxY() - (TG.getY() + TG.getWidth() / 2 - worldScreen.stage.getHeight() / 2));
updateVisualScroll();
}
}

View File

@ -0,0 +1,216 @@
package com.unciv.ui.worldscreen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
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.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.unciv.logic.civilization.CivilizationInfo;
import com.unciv.logic.civilization.Notification;
import com.unciv.models.linq.Linq;
import com.unciv.models.linq.LinqHashMap;
import com.unciv.ui.CivilopediaScreen;
import com.unciv.ui.pickerscreens.PolicyPickerScreen;
import com.unciv.ui.pickerscreens.TechPickerScreen;
import com.unciv.ui.tilegroups.WorldTileGroup;
import com.unciv.ui.utils.CameraStageBaseScreen;
import com.unciv.ui.utils.GameSaver;
import com.unciv.ui.utils.ImageGetter;
public class WorldScreen extends CameraStageBaseScreen {
public TileMapHolder tileMapHolder = new TileMapHolder(this);
float buttonScale = game.settings.buttonScale;
TileInfoTable tileInfoTable = new TileInfoTable(this);
CivStatsTable civTable = new CivStatsTable();
TextButton techButton = new TextButton("", skin);
public LinqHashMap<String, WorldTileGroup> tileGroups = new LinqHashMap<String, WorldTileGroup>();
Table optionsTable = new Table();
NotificationsScroll notificationsScroll = new NotificationsScroll(this);
IdleUnitButton idleUnitButton = new IdleUnitButton(this);
public WorldScreen() {
new Label("", skin).getStyle().font.getData().setScale(game.settings.labelScale);
tileMapHolder.addTiles();
stage.addActor(tileMapHolder);
stage.addActor(tileInfoTable);
stage.addActor(civTable);
stage.addActor(techButton);
stage.addActor(notificationsScroll);
update();
tileMapHolder.setCenterPosition(Vector2.Zero);
createNextTurnButton(); // needs civ table to be positioned
addOptionsTable();
Linq<String> beginningTutorial = new Linq<String>();
beginningTutorial.add("Hello, and welcome to Unciv!" +
"\r\nCivilization games can be complex, so we'll" +
"\r\n be guiding you along your first journey." +
"\r\nBefore we begin, let's review some basic game concepts.");
beginningTutorial.add("This is the world map, which is made up of multiple tiles." +
"\r\nEach tile can contain units, as well as resources" +
"\r\n and improvements, which we'll get to later");
beginningTutorial.add("You start out with two units -" +
"\r\n a Settler - who can found a city," +
"\r\n and a scout, for exploring the area." +
"\r\n Click on a tile to assign orders the unit!");
displayTutorials("NewGame",beginningTutorial);
}
public void update() {
if(game.civInfo.tutorial.contains("CityEntered")){
Linq<String> tutorial = new Linq<String>();
tutorial.add("Once you've done everything you can, " +
"\r\nclick the next turn button on the top right to continue.");
tutorial.add("Each turn, science, culture and gold are added" +
"\r\n to your civilization, your cities' construction" +
"\r\n continues, and they may grow in population or area.");
displayTutorials("NextTurn",tutorial);
}
updateTechButton();
if(tileMapHolder.selectedTile!=null) tileInfoTable.updateTileTable(tileMapHolder.selectedTile);
tileMapHolder.updateTiles();
civTable.update(this);
notificationsScroll.update();
idleUnitButton.update();
if (game.civInfo.tech.freeTechs != 0) {
game.setScreen(new TechPickerScreen(true));
}
else if(game.civInfo.policies.shouldOpenPolicyPicker){
game.setScreen(new PolicyPickerScreen());
game.civInfo.policies.shouldOpenPolicyPicker=false;
}
}
void addOptionsTable() {
Drawable tileTableBackground = ImageGetter.getDrawable("skin/tileTableBackground.png")
.tint(new Color(0x004085bf));
optionsTable.setBackground(tileTableBackground);
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());
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 OpenScienceVictoryScreen = new TextButton("Science victory status", skin);
OpenScienceVictoryScreen.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen(new com.unciv.ui.ScienceVictoryScreen());
}
});
optionsTable.add(OpenScienceVictoryScreen).pad(10);
optionsTable.row();
TextButton OpenPolicyPickerScreen = new TextButton("Social Policies", skin);
OpenPolicyPickerScreen.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen(new PolicyPickerScreen());
}
});
optionsTable.add(OpenPolicyPickerScreen).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.pack(); // Needed to show the background.
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());
}
});
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 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());
return;
}
game.civInfo.nextTurn();
tileMapHolder.unitTile = null;
GameSaver.SaveGame(game, "Autosave");
update();
Linq<String> tutorial = new Linq<String>();
tutorial.add("In your first couple of turns," +
"\r\n you will have very little options," +
"\r\n but as your civilization grows, so do the " +
"\r\n number of things requiring your attention");
displayTutorials("NextTurn",tutorial);
}
});
nextTurnButton.setPosition(stage.getWidth() - nextTurnButton.getWidth() - 10,
civTable.getY() - nextTurnButton.getHeight() - 10);
stage.addActor(nextTurnButton);
}
@Override
public void resize(int width, int height) {
if(stage.getViewport().getScreenWidth()!=width || stage.getViewport().getScreenHeight()!=height) {
super.resize(width, height);
game.worldScreen = new WorldScreen(); // start over.
game.setWorldScreen();
}
}
}