diff --git a/android/build.gradle b/android/build.gradle index 99619a721e..642d9ab508 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,7 +21,7 @@ android { applicationId "com.unciv.game" minSdkVersion 9 targetSdkVersion 25 - versionCode 16 + versionCode 17 versionName "0.9" } buildTypes { diff --git a/core/src/com/unciv/civinfo/CivilizationInfo.java b/core/src/com/unciv/civinfo/CivilizationInfo.java index 8d4190154a..3780c04cf3 100644 --- a/core/src/com/unciv/civinfo/CivilizationInfo.java +++ b/core/src/com/unciv/civinfo/CivilizationInfo.java @@ -35,6 +35,7 @@ public class CivilizationInfo { public int freePolicies=0; public int turns = 1; public LinqCollection notifications = new LinqCollection(); + public LinqCollection tutorial = new LinqCollection(); public LinqCollection cities = new LinqCollection(); diff --git a/core/src/com/unciv/game/CityScreen.java b/core/src/com/unciv/game/CityScreen.java index e4ebd35f5b..212d0383e2 100644 --- a/core/src/com/unciv/game/CityScreen.java +++ b/core/src/com/unciv/game/CityScreen.java @@ -79,6 +79,29 @@ public class CityScreen extends CameraStageBaseScreen { stage.addActor(CityPickerTable); stage.addActor(BuildingsTableContainer); update(); + + LinqCollection tutorial = new LinqCollection(); + tutorial.add("Welcome to your first city!" + + "\r\nAs on now, you only have 1 population," + + "\r\n but this will grow when you amass enough surplus food"); + tutorial.add("Similarly, your city's borders grow when you" + + "\r\n amass enough culture, which is not generated" + + "\r\n by tiles but rather by buildings."); + tutorial.add("Each population in your city can work" + + "\r\n a single tile, providing the city with that tile's yields."); + tutorial.add("Population can be assigned and unassigned" + + "\r\n by clicking on the green population symbols on the tiles - " + + "\r\n but of course, you can only assign population" + + "\r\n if you have idle population to spare!"); + tutorial.add("The center tile off a city is always worked," + + "\r\n and doesn't require population," + + "\r\n but it cannot be improved by tile improvements."); + tutorial.add("The city's production always goes towards the" + + "\r\n current construction - you can pick the city's" + + "\r\n construction by clicking on the construction" + + "\r\n button on the bottom-left"); + + displayTutorials("CityEntered",tutorial); } private void update(){ diff --git a/core/src/com/unciv/game/UnCivGame.java b/core/src/com/unciv/game/UnCivGame.java index 89ee3cb6e6..85f75289b9 100644 --- a/core/src/com/unciv/game/UnCivGame.java +++ b/core/src/com/unciv/game/UnCivGame.java @@ -95,7 +95,8 @@ public class UnCivGame extends Game { for(Building building : GameBasics.Buildings.values()) { if (building.requiredTech == null) continue; TechColumn column = building.GetRequiredTech().column; - building.cost = building.isWonder ? column.wonderCost : column.buildingCost; + if(building.cost==0) + building.cost = building.isWonder ? column.wonderCost : column.buildingCost; } for(PolicyBranch branch : GameBasics.PolicyBranches.values()){ diff --git a/core/src/com/unciv/game/WorldScreen.java b/core/src/com/unciv/game/WorldScreen.java index b96c0db508..462ce7ebaf 100644 --- a/core/src/com/unciv/game/WorldScreen.java +++ b/core/src/com/unciv/game/WorldScreen.java @@ -15,6 +15,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.Drawable; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Predicate; +import com.unciv.civinfo.CivilizationInfo; import com.unciv.civinfo.TileInfo; import com.unciv.game.pickerscreens.ImprovementPickerScreen; import com.unciv.game.pickerscreens.PolicyPickerScreen; @@ -64,7 +65,7 @@ public class WorldScreen extends CameraStageBaseScreen { tileTable.setBackground(tileTableBackground); optionsTable.setBackground(tileTableBackground); - notificationsTable.background(ImageGetter.getSingleColorDrawable(new Color(0x004085bf))); + //notificationsTable.background(ImageGetter.getSingleColorDrawable(new Color(0x004085bf))); TextureRegionDrawable civBackground = ImageGetter.getDrawable("skin/civTableBackground.png"); civTable.setBackground(civBackground.tint(new Color(0x004085bf))); @@ -81,6 +82,20 @@ public class WorldScreen extends CameraStageBaseScreen { setCenterPosition(Vector2.Zero); createNextTurnButton(); // needs civ table to be positioned addOptionsTable(); + + + LinqCollection beginningTutorial = new LinqCollection(); + 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 a single unit - a Settler - who can found a city." + + "\r\nClick on the central tile to assign orders to it!"); + + displayTutorials("NewGame",beginningTutorial); } private void addSelectIdleUnitButton() { @@ -132,14 +147,30 @@ public class WorldScreen extends CameraStageBaseScreen { for (String notification : game.civInfo.notifications) { Label label = new Label(notification, skin); label.setColor(Color.WHITE); - label.setFontScale(0.9f); - notificationsTable.add(label).pad(10).fill(); + label.setFontScale(1.2f); + Table minitable = new Table(); + + minitable.background(ImageGetter.getDrawable("skin/civTableBackground.png") + .tint(new Color(0x004085bf))); + minitable.add(label).pad(5); + + notificationsTable.add(minitable).pad(5); notificationsTable.row(); } notificationsTable.pack(); } public void update() { + if(game.civInfo.tutorial.contains("CityEntered")){ + LinqCollection tutorial = new LinqCollection(); + 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(); @@ -314,6 +345,13 @@ public class WorldScreen extends CameraStageBaseScreen { group.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { + + LinqCollection tutorial = new LinqCollection(); + 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 distanceToTiles = game.civInfo.tileMap.getDistanceToTilesWithinTurn(unitTile.position, unitTile.unit.currentMovement); @@ -455,6 +493,20 @@ public class WorldScreen extends CameraStageBaseScreen { new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { + LinqCollection tutorial = new LinqCollection(); + 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("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"); + 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"); + + 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 diff --git a/core/src/com/unciv/game/pickerscreens/TechPickerScreen.java b/core/src/com/unciv/game/pickerscreens/TechPickerScreen.java index 2a59e13af8..5bd4d16791 100644 --- a/core/src/com/unciv/game/pickerscreens/TechPickerScreen.java +++ b/core/src/com/unciv/game/pickerscreens/TechPickerScreen.java @@ -7,6 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.unciv.civinfo.CivilizationTech; import com.unciv.game.UnCivGame; +import com.unciv.models.LinqCollection; import com.unciv.models.gamebasics.GameBasics; import com.unciv.models.gamebasics.Technology; @@ -29,6 +30,7 @@ public class TechPickerScreen extends PickerScreen { } public TechPickerScreen() { + Technology[][] techMatrix = new Technology[17][10]; // Divided into columns, then rows for (Technology technology : GameBasics.Technologies.linqValues()) { @@ -76,6 +78,18 @@ public class TechPickerScreen extends PickerScreen { dispose(); } }); + + + LinqCollection tutorial = new LinqCollection(); + tutorial.add("Technology is central to your civilization," + + "\r\n as technological progress brings with it" + + "\r\n more construction options, improvements, and abilities"); + tutorial.add("Most technologies are dependant on" + + "\r\n other technologies being researched - " + + "\r\n but you can choose a technology to aspire to," + + "\r\n and your civilization will research the" + + "\r\n necessary technologies to get there"); + displayTutorials("TechPickerScreen",tutorial); } public void setButtonsInfo() { diff --git a/core/src/com/unciv/game/utils/CameraStageBaseScreen.java b/core/src/com/unciv/game/utils/CameraStageBaseScreen.java index 86d295c7d8..d228c46b7c 100644 --- a/core/src/com/unciv/game/utils/CameraStageBaseScreen.java +++ b/core/src/com/unciv/game/utils/CameraStageBaseScreen.java @@ -2,20 +2,25 @@ package com.unciv.game.utils; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.Image; +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.utils.Align; import com.badlogic.gdx.utils.viewport.ExtendViewport; -import com.badlogic.gdx.utils.viewport.FitViewport; -import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.unciv.civinfo.CivilizationInfo; import com.unciv.game.UnCivGame; +import com.unciv.models.LinqCollection; -import java.util.HashMap; +import java.util.Collection; +import java.util.Collections; public class CameraStageBaseScreen implements Screen { @@ -33,9 +38,7 @@ public class CameraStageBaseScreen implements Screen { @Override - public void show() { - - } + public void show() { } @Override public void render(float delta) { @@ -52,24 +55,46 @@ public class CameraStageBaseScreen implements Screen { } @Override - public void pause() { - - } + public void pause() { } @Override - public void resume() { - - } + public void resume() { } @Override - public void hide() { - - } + public void hide() { } @Override - public void dispose() { + public void dispose() { } + public void displayTutorials(String name, LinqCollection texts){ + if(CivilizationInfo.current().tutorial.contains(name)) return; + CivilizationInfo.current().tutorial.add(name); + displayTutorial(texts); } + public void displayTutorial(final LinqCollection texts){ + + final Table tutorialTable = new Table().pad(10); + tutorialTable.background(ImageGetter.getDrawable("skin/tileTableBackground.png") + .tint(new Color(0x101050cf))); + Label label = new Label(texts.get(0),skin); + label.setFontScale(1.5f); + label.setAlignment(Align.center); + texts.remove(0); + tutorialTable.add(label).pad(10).row(); + TextButton button = new TextButton("Close",skin); + button.addListener(new ClickListener(){ + @Override + public void clicked(InputEvent event, float x, float y) { + tutorialTable.remove(); + if(!texts.isEmpty()) displayTutorial(texts); + } + }); + tutorialTable.add(button).pad(10); + tutorialTable.pack(); + tutorialTable.setPosition(stage.getWidth()/2-tutorialTable.getWidth()/2, + stage.getHeight()/2-tutorialTable.getHeight()/2); + stage.addActor(tutorialTable); + } } \ No newline at end of file diff --git a/core/src/com/unciv/game/utils/ImageGetter.java b/core/src/com/unciv/game/utils/ImageGetter.java index 87fcf5fa61..9eb83676a0 100644 --- a/core/src/com/unciv/game/utils/ImageGetter.java +++ b/core/src/com/unciv/game/utils/ImageGetter.java @@ -19,7 +19,10 @@ public class ImageGetter { } public static TextureRegionDrawable getDrawable(String fileName) { - return new TextureRegionDrawable(getTextureRegion(fileName)); + TextureRegionDrawable drawable = new TextureRegionDrawable(getTextureRegion(fileName)); + drawable.setMinHeight(0); + drawable.setMinWidth(0); + return drawable; } public static Drawable getSingleColorDrawable(Color color){