Classic data backup dialog

This commit is contained in:
Anuken 2019-08-13 15:14:03 -04:00
parent f2f6dc89a2
commit 974ab59fd2
23 changed files with 129 additions and 46 deletions

View File

@ -34,6 +34,7 @@ public class AndroidLauncher extends AndroidApplication{
public static final int PERMISSION_REQUEST_CODE = 1;
boolean doubleScaleTablets = true;
FileChooser chooser;
Runnable permCallback;
@Override
protected void onCreate(Bundle savedInstanceState){
@ -66,6 +67,24 @@ public class AndroidLauncher extends AndroidApplication{
}
}
@Override
public void requestExternalPerms(Runnable callback){
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){
callback.run();
}else{
permCallback = callback;
ArrayList<String> perms = new ArrayList<>();
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE);
}
}
@Override
public void shareFile(FileHandle file){
}
@ -123,7 +142,11 @@ public class AndroidLauncher extends AndroidApplication{
if(i != PackageManager.PERMISSION_GRANTED) return;
}
if(chooser != null){
chooser.show();
Core.app.post(chooser::show);
}
if(permCallback != null){
Core.app.post(permCallback);
permCallback = null;
}
}
}

View File

@ -157,6 +157,8 @@ cancel = Cancel
openlink = Open Link
copylink = Copy Link
back = Back
classic.export = Export Classic Data
classic.export.text = Classic (v3.5 build 40) save or map data has been detected. Would you like to export these saves to your phone's home folder, for use in the Mindustry Classic app?
quit.confirm = Are you sure you want to quit?
quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[]
loading = [accent]Loading...
@ -435,7 +437,7 @@ blocks.shots = Shots
blocks.reload = Shots/Second
blocks.ammo = Ammo
bar.drilltierreq = Better Drill Required
bar.drillspeed = Drill Speed: {0}/s
bar.efficiency = Efficiency: {0}%
bar.powerbalance = Power: {0}/s

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
core/assets/sounds/wave.ogg Normal file

Binary file not shown.

View File

@ -102,6 +102,7 @@ public class UnitTypes implements ContentList{
weapon = new Weapon("bomber"){{
reload = 12f;
ejectEffect = Fx.none;
shootSound = Sounds.explosion;
bullet = new BombBulletType(2f, 3f, "clear"){
{
hitEffect = Fx.pulverize;
@ -233,6 +234,7 @@ public class UnitTypes implements ContentList{
shotDelay = 3;
ejectEffect = Fx.shellEjectMedium;
bullet = Bullets.standardThoriumBig;
shootSound = Sounds.shootBig;
}};
}};
@ -251,6 +253,7 @@ public class UnitTypes implements ContentList{
roundrobin = true;
ejectEffect = Fx.shellEjectSmall;
bullet = Bullets.standardCopper;
shootSound = Sounds.shoot;
}};
}};
@ -274,7 +277,7 @@ public class UnitTypes implements ContentList{
inaccuracy = 40f;
ignoreRotation = true;
bullet = Bullets.bombExplosive;
shootSound = Sounds.release;
shootSound = Sounds.none;
}};
}};

View File

@ -1,7 +1,7 @@
package io.anuke.mindustry.core;
import io.anuke.arc.Application.*;
import io.anuke.arc.*;
import io.anuke.arc.files.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.input.*;
@ -39,11 +39,11 @@ public class Control implements ApplicationListener{
public final Saves saves;
public final MusicControl music;
public final Tutorial tutorial;
public InputHandler input;
private Interval timer = new Interval(2);
private boolean hiscore = false;
private boolean wasPaused = false;
private InputHandler input;
public Control(){
batch = new SpriteBatch();
@ -117,6 +117,7 @@ public class Control implements ApplicationListener{
hiscore = true;
world.getMap().setHighScore(state.wave);
}
Sounds.wave.play();
});
Events.on(GameOverEvent.class, event -> {
@ -177,8 +178,39 @@ public class Control implements ApplicationListener{
ui.hudfrag.showToast(Core.bundle.format("zone.config.complete", e.zone.configureWave));
});
if(Core.app.getType() == ApplicationType.Android){
if(android){
Sounds.empty.loop(0f, 1f, 0f);
checkClassicData();
}
}
//checks for existing 3.5 app data, android only
public void checkClassicData(){
try{
if(files.local("mindustry-maps").exists() || files.local("mindustry-saves").exists()){
settings.getBoolOnce("classic-backup-check", () -> {
app.post(() -> app.post(() -> ui.showConfirm("$classic.export", "$classic.export.text", () -> {
try{
Platform.instance.requestExternalPerms(() -> {
FileHandle external = files.external("MindustryClassic");
if(files.local("mindustry-maps").exists()){
files.local("mindustry-maps").copyTo(external);
}
if(files.local("mindustry-saves").exists()){
files.local("mindustry-saves").copyTo(external);
}
});
}catch(Exception e){
e.printStackTrace();
ui.showError(Strings.parseException(e, true));
}
})));
});
}
}catch(Throwable t){
t.printStackTrace();
}
}
@ -202,10 +234,6 @@ public class Control implements ApplicationListener{
Core.input.addProcessor(input);
}
public InputHandler input(){
return input;
}
public void playMap(Map map, Rules rules){
ui.loadAnd(() -> {
logic.reset();

View File

@ -39,6 +39,11 @@ public abstract class Platform{
});
}
/** Request external read/write perms. Run callback when complete.*/
public void requestExternalPerms(Runnable callback){
callback.run();
}
/** Update discord RPC. */
public void updateRPC(){
}

View File

@ -214,7 +214,7 @@ public class UI implements ApplicationListener{
Core.scene.add(menuGroup);
Core.scene.add(hudGroup);
control.input().getFrag().build(hudGroup);
control.input.getFrag().build(hudGroup);
hudfrag.build(hudGroup);
menufrag.build(menuGroup);
chatfrag.container().build(hudGroup);

View File

@ -1,5 +1,6 @@
package io.anuke.mindustry.entities.traits;
import io.anuke.annotations.Annotations.*;
import io.anuke.arc.Core;
import io.anuke.arc.Events;
import io.anuke.arc.collection.Array;
@ -206,7 +207,7 @@ public interface BuilderTrait extends Entity, TeamTrait{
* Return the build requests currently active, or the one at the top of the queue.
* May return null.
*/
default BuildRequest buildRequest(){
default @Nullable BuildRequest buildRequest(){
return buildQueue().size == 0 ? null : buildQueue().first();
}

View File

@ -19,7 +19,7 @@ import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.input.Binding;
import io.anuke.mindustry.input.*;
import io.anuke.mindustry.input.InputHandler.PlaceDraw;
import io.anuke.mindustry.io.TypeIO;
import io.anuke.mindustry.net.Net;
@ -70,7 +70,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
private Tile mining;
private Vector2 movement = new Vector2();
private boolean moved;
private SoundLoop sound = new SoundLoop(Sounds.thruster, 2f);
private SoundLoop boostSound = new SoundLoop(Sounds.thruster, 2f), buildSound = new SoundLoop(Sounds.build, 0.75f);
//endregion
@ -133,7 +133,8 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
@Override
public void removed(){
sound.stop();
boostSound.stop();
buildSound.stop();
}
@Override
@ -513,7 +514,9 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
destructTime = 0f;
}
sound.update(x, y, isBoosting && !isDead() && !mech.flying);
boostSound.update(x, y, isBoosting && !isDead() && !mech.flying);
BuildRequest request = buildRequest();
buildSound.update(request == null ? x : request.x * tilesize, request == null ? y : request.y * tilesize, isBuilding() && (Mathf.within(request.x * tilesize, request.y * tilesize, x, y, placeDistance) || state.isEditor()));
if(isDead()){
isBoosting = false;
@ -606,7 +609,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
movement.x += xa * speed;
}
Vector2 vec = Core.input.mouseWorld(control.input().getMouseX(), control.input().getMouseY());
Vector2 vec = Core.input.mouseWorld(control.input.getMouseX(), control.input.getMouseY());
pointerX = vec.x;
pointerY = vec.y;
updateShooting();
@ -629,7 +632,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
rotation = Mathf.slerpDelta(rotation, mech.flying ? velocity.angle() : movement.angle(), 0.13f * baseLerp);
}
}else{
float angle = control.input().mouseAngle(x, y);
float angle = control.input.mouseAngle(x, y);
this.rotation = Mathf.slerpDelta(this.rotation, angle, 0.1f * baseLerp);
}
}
@ -758,8 +761,8 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
}
}else if(isShooting()){
Vector2 vec = Core.input.mouseWorld(control.input().getMouseX(),
control.input().getMouseY());
Vector2 vec = Core.input.mouseWorld(control.input.getMouseX(),
control.input.getMouseY());
pointerX = vec.x;
pointerY = vec.y;

View File

@ -33,6 +33,7 @@ public class SoundLoop{
if(volume <= 0.001f){
sound.stop(id);
id = -1;
return;
}
}
sound.setPan(id, sound.calcPan(x, y), sound.calcVolume(x, y) * volume * baseVolume);

View File

@ -105,6 +105,7 @@ public class Tutorial{
void draw(){
outline("category-production");
outline("block-mechanical-drill");
outline("confirmplace");
}
},
blockinfo(() -> event("blockinfo")){

View File

@ -27,7 +27,7 @@ public class OverlayRenderer{
private float buildFadeTime;
public void drawBottom(){
InputHandler input = control.input();
InputHandler input = control.input;
if(!input.isDrawing() || player.isDead()) return;
@ -64,7 +64,7 @@ public class OverlayRenderer{
if(player.isDead()) return; //dead players don't draw
InputHandler input = control.input();
InputHandler input = control.input;
//draw config selected block
if(input.frag.config.isShown()){

View File

@ -289,7 +289,7 @@ public class MobileInput extends InputHandler implements GestureListener{
removals.addAll(selection);
selection.clear();
selecting = false;
}).visible(() -> !selection.isEmpty());
}).visible(() -> !selection.isEmpty()).name("confirmplace");
Core.scene.table(t -> {
t.bottom().left().visible(() -> (player.isBuilding() || block != null || mode == breaking) && !state.is(State.menu));

View File

@ -54,7 +54,7 @@ public class Weapon{
/** whether shooter rotation is ignored when shooting. */
public boolean ignoreRotation = false;
public Sound shootSound = Sounds.shoot;
public Sound shootSound = Sounds.pew;
public TextureRegion region;

View File

@ -193,6 +193,20 @@ public class SettingsMenuDialog extends SettingsDialog{
}
});
if(android && (Core.files.local("mindustry-maps").exists() || Core.files.local("mindustry-saves").exists())){
game.pref(new Setting(){
@Override
public void add(SettingsTable table){
table.addButton("$classic.export", () -> {
control.checkClassicData();
}).size(220f, 60f).pad(6).left();
table.add();
table.row();
hide();
}
});
}
graphics.sliderPref("uiscale", 100, 25, 400, 25, s -> {
if(Core.graphics.getFrameId() > 10){
Log.info("changed");

View File

@ -53,7 +53,7 @@ public class PlacementFragment extends Fragment{
public PlacementFragment(){
Events.on(WorldLoadEvent.class, event -> {
Core.app.post(() -> {
control.input().block = null;
control.input.block = null;
rebuild();
});
});
@ -119,7 +119,7 @@ public class PlacementFragment extends Fragment{
full.bottom().right().visible(() -> ui.hudfrag.shown());
full.table(frame -> {
InputHandler input = control.input();
InputHandler input = control.input;
//rebuilds the category table with the correct recipes
Runnable rebuildCategory = () -> {
@ -336,8 +336,8 @@ public class PlacementFragment extends Fragment{
}
//block currently selected
if(control.input().block != null){
toDisplay = control.input().block;
if(control.input.block != null){
toDisplay = control.input.block;
}
//block hovered on in build menu

View File

@ -28,7 +28,7 @@ public class ItemSelection{
for(Item item : items){
if(!data.isUnlocked(item) && world.isZone()) continue;
ImageButton button = cont.addImageButton("whiteui", "clear-toggle-trans", 24, () -> control.input().frag.config.hideConfig()).group(group).get();
ImageButton button = cont.addImageButton("whiteui", "clear-toggle-trans", 24, () -> control.input.frag.config.hideConfig()).group(group).get();
button.changed(() -> consumer.accept(button.isChecked() ? item : null));
button.getStyle().imageUp = new TextureRegionDrawable(item.icon(Icon.medium));
button.update(() -> button.setChecked(holder.get() == item));

View File

@ -1,21 +1,18 @@
package io.anuke.mindustry.world.blocks.power;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.Blending;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.*;
import io.anuke.arc.util.*;
import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.ui.Bar;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.meta.*;
import java.io.*;
@ -130,6 +127,8 @@ public class ImpactReactor extends PowerGenerator{
if(entity.warmup < 0.4f) return;
Sounds.explosionbig.at(tile);
Effects.shake(6f, 16f, tile.worldx(), tile.worldy());
Effects.effect(Fx.impactShockwave, tile.worldx(), tile.worldy());
for(int i = 0; i < 6; i++){

View File

@ -10,6 +10,7 @@ import io.anuke.mindustry.content.Fx;
import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Liquid;
@ -118,6 +119,8 @@ public class NuclearReactor extends PowerGenerator{
public void onDestroyed(Tile tile){
super.onDestroyed(tile);
Sounds.explosionbig.at(tile);
NuclearReactorEntity entity = tile.entity();
int fuel = entity.items.get(consumes.<ConsumeItems>get(ConsumeType.item).items[0].item);

View File

@ -83,10 +83,10 @@ public class LiquidSource extends Block{
for(int i = 0; i < items.size; i++){
final int f = i;
ImageButton button = cont.addImageButton("clear", "clear-toggle-trans", 24, () -> control.input().frag.config.hideConfig()).size(38).group(group).get();
ImageButton button = cont.addImageButton("clear", "clear-toggle-trans", 24, () -> control.input.frag.config.hideConfig()).size(38).group(group).get();
button.changed(() -> {
Call.setLiquidSourceLiquid(null, tile, button.isChecked() ? items.get(f) : null);
control.input().frag.config.hideConfig();
control.input.frag.config.hideConfig();
lastLiquid = items.get(f);
});
button.getStyle().imageUp = new TextureRegionDrawable(items.get(i).iconRegion);