diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 9903993f5c..4a5672e505 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -171,6 +171,7 @@ text.blocks.fuelduration=Fuel Duration text.blocks.maxoutputsecond=Max output/second text.blocks.inputcapacity=Input capacity text.blocks.outputcapacity=Output capacity +text.blocks.poweritem=Power/Item text.placemode=Place Mode text.breakmode=Break Mode text.health=health @@ -385,7 +386,7 @@ block.powerlaserrouter.fulldescription=Laser that distributes power to three dir block.powerlasercorner.name=laser corner block.powerlasercorner.fulldescription=Laser that distributes power to two directions at once. Useful in situations where it is required to power multiple blocks from one generator, and a router is imprecise. block.teleporter.name=teleporter -block.teleporter.fulldescription=Advanced item transport block. Teleporters input items to other teleporters of the same color. Does nothing if no teleporters of the same color exist. If multiple teleporters exist of the same color, a random one is selected. Tap and click the arrows to change color. +block.teleporter.fulldescription=Advanced item transport block. Teleporters input items to other teleporters of the same color. Does nothing if no teleporters of the same color exist. If multiple teleporters exist of the same color, a random one is selected. Uses power. Tap to change color. block.sorter.name=sorter block.sorter.fulldescription=Sorts item by material type. Material to accept is indicated by the color in the block. All items that match the sort material are outputted forward, everything else is outputted to the left and right. block.core.name=core diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 572770fa43..7c89f9cabf 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -24,7 +24,7 @@ public class Vars{ //waves can last no longer than 3 minutes, otherwise the next one spawns public static final float maxwavespace = 60*60*4f; //advance time the pathfinding starts at - public static final float aheadPathfinding = 60*20; + public static final float aheadPathfinding = 60*15; //how far away from spawn points the player can't place blocks public static final float enemyspawnspace = 65; //discord group URL diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 3ee8003968..a8e1a74a9a 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -409,7 +409,7 @@ public class Control extends Module{ } public boolean isGameOver(){ - return core.block() != ProductionBlocks.core; + return core != null && core.block() != ProductionBlocks.core; } float waveSpacing(){ diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index dc3da1ad26..81c074cf06 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -154,11 +154,11 @@ public class NetClient extends Module { }); Net.handle(PlacePacket.class, packet -> { - Vars.control.input.placeBlockInternal(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, false); + Gdx.app.postRunnable(() -> Vars.control.input.placeBlockInternal(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, false)); }); Net.handle(BreakPacket.class, packet -> { - Vars.control.input.breakBlockInternal(packet.x, packet.y, false); + Gdx.app.postRunnable(() -> Vars.control.input.breakBlockInternal(packet.x, packet.y, false)); }); Net.handle(StateSyncPacket.class, packet -> { diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 600926d989..29388da57e 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -307,6 +307,8 @@ public class NetServer extends Module{ BlockSyncPacket packet = new BlockSyncPacket(); ByteArrayOutputStream bs = new ByteArrayOutputStream(); + //TODO compress stream + try { DataOutputStream stream = new DataOutputStream(bs); diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index ab5523fe69..fb2ad42cb7 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -39,7 +39,7 @@ public class Player extends DestructibleEntity implements Syncable{ hitbox.setSize(5); hitboxTile.setSize(4f); - maxhealth = 100; + maxhealth = 150; heal(); } diff --git a/core/src/io/anuke/mindustry/input/AndroidInput.java b/core/src/io/anuke/mindustry/input/AndroidInput.java index bb164cdacf..a4f8a0034b 100644 --- a/core/src/io/anuke/mindustry/input/AndroidInput.java +++ b/core/src/io/anuke/mindustry/input/AndroidInput.java @@ -9,7 +9,6 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Timers; @@ -75,7 +74,7 @@ public class AndroidInput extends InputHandler{ Tile cursor = world.tile(Mathf.scl2(Graphics.mouseWorld().x, tilesize), Mathf.scl2(Graphics.mouseWorld().y, tilesize)); if(cursor != null && !ui.hasMouse(screenX, screenY)){ Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor; - if(linked != null && linked.block() instanceof Configurable){ + if(linked != null && linked.block().isConfigurable(linked)){ ui.configfrag.showConfig(linked); }else if(!ui.configfrag.hasConfigMouse()){ ui.configfrag.hideConfig(); diff --git a/core/src/io/anuke/mindustry/input/DesktopInput.java b/core/src/io/anuke/mindustry/input/DesktopInput.java index 9929ca94a2..a211b27414 100644 --- a/core/src/io/anuke/mindustry/input/DesktopInput.java +++ b/core/src/io/anuke/mindustry/input/DesktopInput.java @@ -8,7 +8,6 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Timers; @@ -92,7 +91,7 @@ public class DesktopInput extends InputHandler{ if(Inputs.keyTap("select") && cursor != null && !ui.hasMouse()){ Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor; - if(linked != null && linked.block() instanceof Configurable){ + if(linked != null && linked.block().isConfigurable(linked)){ ui.configfrag.showConfig(linked); }else if(!ui.configfrag.hasConfigMouse()){ ui.configfrag.hideConfig(); diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index a8529a7781..2b2e19f715 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -17,7 +17,6 @@ import io.anuke.mindustry.world.SpawnPoint; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.ProductionBlocks; -import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Sounds; @@ -51,7 +50,7 @@ public abstract class InputHandler extends InputAdapter{ public boolean onConfigurable(){ Tile tile = Vars.world.tile(getBlockX(), getBlockY()); - return tile != null && (tile.block() instanceof Configurable || (tile.isLinked() && tile.getLinked().block() instanceof Configurable)); + return tile != null && (tile.block().isConfigurable(tile) || (tile.isLinked() && tile.getLinked().block().isConfigurable(tile))); } public boolean cursorNear(){ diff --git a/core/src/io/anuke/mindustry/resource/Recipe.java b/core/src/io/anuke/mindustry/resource/Recipe.java index 9030f4ea34..e7e1910028 100644 --- a/core/src/io/anuke/mindustry/resource/Recipe.java +++ b/core/src/io/anuke/mindustry/resource/Recipe.java @@ -6,10 +6,16 @@ public class Recipe { public Block result; public ItemStack[] requirements; public Section section; + public boolean desktopOnly = false; public Recipe(Section section, Block result, ItemStack... requirements){ this.result = result; this.requirements = requirements; this.section = section; } + + public Recipe setDesktop(){ + desktopOnly = true; + return this; + } } diff --git a/core/src/io/anuke/mindustry/resource/Recipes.java b/core/src/io/anuke/mindustry/resource/Recipes.java index e29d5e533e..a6739278dd 100644 --- a/core/src/io/anuke/mindustry/resource/Recipes.java +++ b/core/src/io/anuke/mindustry/resource/Recipes.java @@ -1,6 +1,7 @@ package io.anuke.mindustry.resource; import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.blocks.DefenseBlocks; import io.anuke.mindustry.world.blocks.DistributionBlocks; @@ -19,8 +20,8 @@ public class Recipes { new Recipe(defense, DefenseBlocks.steelwalllarge, stack(Item.steel, 12*4)), new Recipe(defense, DefenseBlocks.titaniumwalllarge, stack(Item.titanium, 12*4)), new Recipe(defense, DefenseBlocks.diriumwalllarge, stack(Item.dirium, 12*4)), - new Recipe(defense, DefenseBlocks.door, stack(Item.steel, 3), stack(Item.iron, 3*4)), - new Recipe(defense, DefenseBlocks.largedoor, stack(Item.steel, 3*4), stack(Item.iron, 3*4*4)), + new Recipe(defense, DefenseBlocks.door, stack(Item.steel, 3), stack(Item.iron, 3*4)).setDesktop(), + new Recipe(defense, DefenseBlocks.largedoor, stack(Item.steel, 3*4), stack(Item.iron, 3*4*4)).setDesktop(), new Recipe(defense, DefenseBlocks.titaniumshieldwall, stack(Item.titanium, 16)), new Recipe(distribution, DistributionBlocks.conveyor, stack(Item.stone, 1)), @@ -55,7 +56,7 @@ public class Recipes { new Recipe(crafting, ProductionBlocks.oilrefinery, stack(Item.steel, 15), stack(Item.iron, 15)), new Recipe(crafting, ProductionBlocks.stoneformer, stack(Item.steel, 10), stack(Item.iron, 10)), new Recipe(crafting, ProductionBlocks.lavasmelter, stack(Item.steel, 30), stack(Item.titanium, 15)), - new Recipe(crafting, ProductionBlocks.weaponFactory, stack(Item.steel, 60), stack(Item.iron, 60)), + new Recipe(crafting, ProductionBlocks.weaponFactory, stack(Item.steel, 60), stack(Item.iron, 60)).setDesktop(), new Recipe(production, ProductionBlocks.stonedrill, stack(Item.stone, 12)), new Recipe(production, ProductionBlocks.irondrill, stack(Item.stone, 25)), @@ -104,8 +105,8 @@ public class Recipes { public static Array getBy(Section section, Array r){ for(Recipe recipe : list){ - if(recipe.section == section) - r.add(recipe); + if(recipe.section == section && !(Vars.android && recipe.desktopOnly)) + r.add(recipe); } return r; diff --git a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java index dddb9bdcaf..2a0b1ccdd1 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -27,7 +27,6 @@ public class SettingsMenuDialog extends SettingsDialog{ private Table prefs; private Table menu; - private boolean built = false; private boolean wasPaused; public SettingsMenuDialog(){ @@ -114,20 +113,20 @@ public class SettingsMenuDialog extends SettingsDialog{ game.checkPref("indicators", true); game.checkPref("effects", true); game.sliderPref("sensitivity", 100, 10, 300, i -> i + "%"); - game.sliderPref("saveinterval", 90, 15, 5*120, i -> Bundles.format("setting.seconds", i)); + game.sliderPref("saveinterval", 90, 10, 5*120, i -> Bundles.format("setting.seconds", i)); graphics.checkPref("fps", false); graphics.checkPref("vsync", true, b -> Gdx.graphics.setVSync(b)); graphics.checkPref("lasers", true); graphics.checkPref("healthbars", true); - graphics.checkPref("pixelate", true, b->{ + graphics.checkPref("pixelate", true, b -> { if(b){ - Vars.renderer.pixelSurface.setScale(Core.cameraScale); - Vars.renderer.shadowSurface.setScale(Core.cameraScale); - Vars.renderer.shieldSurface.setScale(Core.cameraScale); + renderer.pixelSurface.setScale(Core.cameraScale); + renderer.shadowSurface.setScale(Core.cameraScale); + renderer.shieldSurface.setScale(Core.cameraScale); }else{ - Vars.renderer.shadowSurface.setScale(1); - Vars.renderer.shieldSurface.setScale(1); + renderer.shadowSurface.setScale(1); + renderer.shieldSurface.setScale(1); } renderer.setPixelate(b); }); diff --git a/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java b/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java index f493f0e347..76c0ca49ab 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/BlockConfigFragment.java @@ -6,7 +6,6 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Align; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; -import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.scene.Element; @@ -35,7 +34,7 @@ public class BlockConfigFragment implements Fragment { configTile = tile; table.clear(); - ((Configurable)tile.block()).buildTable(tile, table); + tile.block().buildTable(tile, table); table.pack(); table.setTransform(true); table.actions(Actions.scaleTo(0f, 1f), Actions.visible(true), diff --git a/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java b/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java index 53c9b7914c..bcc9d00eca 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/ChatFragment.java @@ -80,6 +80,9 @@ public class ChatFragment extends Table implements Fragment{ bottom().left().marginBottom(offsety).marginLeft(offsetx*2).add(fieldlabel).padBottom(4f); add(chatfield).padBottom(offsety).padLeft(offsetx).growX().padRight(offsetx).height(28); + if(Vars.android) { + addImageButton("icon-chat", 14 * 2, this::toggle).size(30f).visible(() -> chatOpen); + } } @Override @@ -144,6 +147,7 @@ public class ChatFragment extends Table implements Fragment{ if(!chatOpen && (scene.getKeyboardFocus() == null || !scene.getKeyboardFocus().getParent().isVisible())){ scene.setKeyboardFocus(chatfield); + chatfield.fireClick(); chatOpen = !chatOpen; fadetime = messagesShown + 1; }else if(chatOpen){ @@ -154,6 +158,12 @@ public class ChatFragment extends Table implements Fragment{ } } + public void hide(){ + scene.setKeyboardFocus(null); + chatOpen = false; + chatfield.setText(""); + } + public boolean chatOpen(){ return chatOpen; } diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index ddc20f59e0..0bda06012b 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -64,8 +64,11 @@ public class HudFragment implements Fragment{ pause = new imagebutton("icon-pause", isize, ()->{ if(Net.active() && Vars.android){ - //TODO open android chat - ui.chatfrag.toggle(); + if(ui.chatfrag.chatOpen()){ + ui.chatfrag.hide(); + }else{ + ui.chatfrag.toggle(); + } }else { GameState.set(GameState.is(State.paused) ? State.playing : State.paused); } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index 28c03a6498..d45857dc7f 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -3,7 +3,6 @@ package io.anuke.mindustry.world; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; - import com.badlogic.gdx.utils.ObjectMap; import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState; @@ -16,6 +15,7 @@ import io.anuke.mindustry.resource.Liquid; import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects.Effect; +import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Tmp; @@ -106,7 +106,13 @@ public class Block{ public void drawPlace(int x, int y, int rotation, boolean valid){} public void postInit(){} public void placed(Tile tile){} + public void tapped(Tile tile){} + public void buildTable(Tile tile, Table table) {} + + public boolean isConfigurable(Tile tile){ + return false; + } public void getStats(Array list){ list.add("[gray]size: " + width + "x" + height); diff --git a/core/src/io/anuke/mindustry/world/blocks/types/Configurable.java b/core/src/io/anuke/mindustry/world/blocks/types/Configurable.java deleted file mode 100644 index b59ad48f1e..0000000000 --- a/core/src/io/anuke/mindustry/world/blocks/types/Configurable.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.anuke.mindustry.world.blocks.types; - -import io.anuke.mindustry.world.Tile; -import io.anuke.ucore.scene.ui.layout.Table; - -public interface Configurable{ - public void buildTable(Tile tile, Table table); -} diff --git a/core/src/io/anuke/mindustry/world/blocks/types/distribution/Sorter.java b/core/src/io/anuke/mindustry/world/blocks/types/distribution/Sorter.java index 3cad9e690b..e74f998b9b 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/distribution/Sorter.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/distribution/Sorter.java @@ -5,7 +5,6 @@ import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.style.TextureRegionDrawable; @@ -19,7 +18,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class Sorter extends Junction implements Configurable{ +public class Sorter extends Junction{ public Sorter(String name) { super(name); @@ -90,6 +89,11 @@ public class Sorter extends Junction implements Configurable{ return to; } + + @Override + public boolean isConfigurable(Tile tile){ + return true; + } @Override public void buildTable(Tile tile, Table table){ diff --git a/core/src/io/anuke/mindustry/world/blocks/types/distribution/Teleporter.java b/core/src/io/anuke/mindustry/world/blocks/types/distribution/Teleporter.java index e8e814922d..d47f238e66 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/distribution/Teleporter.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/distribution/Teleporter.java @@ -6,7 +6,6 @@ import com.badlogic.gdx.utils.ObjectSet; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.mindustry.world.blocks.types.PowerBlock; import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Timers; @@ -20,8 +19,9 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -public class Teleporter extends PowerBlock implements Configurable{ - public static final Color[] colorArray = {Color.ROYAL, Color.ORANGE, Color.SCARLET, Color.FOREST, Color.PURPLE, Color.GOLD, Color.PINK, Color.BLACK}; +public class Teleporter extends PowerBlock{ + public static final Color[] colorArray = {Color.ROYAL, Color.ORANGE, Color.SCARLET, Color.FOREST, + Color.PURPLE, Color.GOLD, Color.PINK, Color.BLACK}; public static final int colors = colorArray.length; private static ObjectSet[] teleporters = new ObjectSet[colors]; @@ -81,6 +81,11 @@ public class Teleporter extends PowerBlock implements Configurable{ tryDump(tile); } } + + @Override + public boolean isConfigurable(Tile tile){ + return true; + } @Override public void buildTable(Tile tile, Table table){ diff --git a/core/src/io/anuke/mindustry/world/blocks/types/production/WeaponFactory.java b/core/src/io/anuke/mindustry/world/blocks/types/production/WeaponFactory.java index 170785f90d..ac4c32c9d2 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/production/WeaponFactory.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/production/WeaponFactory.java @@ -8,7 +8,6 @@ import io.anuke.mindustry.resource.UpgradeRecipes; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; -import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Effects; import io.anuke.ucore.function.Listenable; @@ -19,7 +18,7 @@ import io.anuke.ucore.scene.ui.layout.Table; import static io.anuke.mindustry.Vars.control; -public class WeaponFactory extends Block implements Configurable{ +public class WeaponFactory extends Block{ public WeaponFactory(String name){ super(name); @@ -27,6 +26,11 @@ public class WeaponFactory extends Block implements Configurable{ destructible = true; } + @Override + public boolean isConfigurable(Tile tile){ + return !Vars.android; + } + @Override public void buildTable(Tile tile, Table table) { int i = 0; diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index d916f81bed..09de35415b 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -129,9 +129,10 @@ public class DesktopLauncher { String result = Strings.parseException(e, true); boolean failed = false; - String filename = "crash-report-" + new SimpleDateFormat("dd-MM-yy h.mm.ss").format(new Date()) + ".txt"; + String filename = ""; try{ + filename = "crash-report-" + new SimpleDateFormat("dd-MM-yy h.mm.ss").format(new Date()) + ".txt"; Files.write(Paths.get(filename), result.getBytes()); }catch (IOException i){ i.printStackTrace();