diff --git a/android/build.gradle b/android/build.gradle index 5f355a0ec7..d073b66a15 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,6 +7,7 @@ buildscript{ } dependencies{ + //note that later versions, like alpha05, fail to work correctly classpath 'com.android.tools.build:gradle:7.1.0-alpha02' } } @@ -18,7 +19,6 @@ configurations{ natives } repositories{ mavenCentral() maven{ url "https://maven.google.com" } - jcenter() //remove later once google/JetBrains fixes the dependency } task deploy(type: Copy){ diff --git a/core/src/mindustry/Vars.java b/core/src/mindustry/Vars.java index 6343998991..f27fc0f77c 100644 --- a/core/src/mindustry/Vars.java +++ b/core/src/mindustry/Vars.java @@ -103,8 +103,6 @@ public class Vars implements Loadable{ public static final float invasionGracePeriod = 20; /** min armor fraction damage; e.g. 0.05 = at least 5% damage */ public static final float minArmorDamage = 0.1f; - /** launch animation duration */ - public static final float launchDuration = 140f; /** land animation duration */ public static final float coreLandDuration = 150f; /** size of tiles in units */ diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index 936fc15ea1..ff42a5e6c0 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -544,7 +544,7 @@ public class Control implements ApplicationListener, Loadable{ core.items.each((i, a) -> i.unlock()); } - if(Core.input.keyTap(Binding.pause) && !scene.hasDialog() && !scene.hasKeyboard() && !ui.restart.isShown() && (state.is(State.paused) || state.is(State.playing))){ + if(Core.input.keyTap(Binding.pause) && !renderer.isCutscene() && !scene.hasDialog() && !scene.hasKeyboard() && !ui.restart.isShown() && (state.is(State.paused) || state.is(State.playing))){ state.set(state.is(State.playing) ? State.paused : State.playing); } diff --git a/core/src/mindustry/core/Renderer.java b/core/src/mindustry/core/Renderer.java index 32d93fe5dc..4d107c06ed 100644 --- a/core/src/mindustry/core/Renderer.java +++ b/core/src/mindustry/core/Renderer.java @@ -31,7 +31,7 @@ public class Renderer implements ApplicationListener{ private static final float cloudScaling = 1700f, cfinScl = -2f, cfinOffset = 0.3f, calphaFinOffset = 0.25f; private static final float[] cloudAlphas = {0, 0.5f, 1f, 0.1f, 0, 0f}; private static final float cloudAlpha = 0.81f; - private static final float[] thrusterSize = {0f, 0f, 0f, 0f, 0.3f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0f}; + private static final float[] thrusterSizes = {0f, 0f, 0f, 0f, 0.3f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0f}; private static final Interp landInterp = Interp.pow3; public final BlockRenderer blocks = new BlockRenderer(); @@ -70,7 +70,7 @@ public class Renderer implements ApplicationListener{ //current duration of screen shake shakeTime; //for landTime > 0: if true, core is currently *launching*, otherwise landing. - private boolean isLaunching; + private boolean launching; private Vec2 camShakeOffset = new Vec2(); public Renderer(){ @@ -129,7 +129,9 @@ public class Renderer implements ApplicationListener{ if(!state.isPaused()){ landTime -= Time.delta; } - camerascale = landInterp.apply(minZoomScl, Scl.scl(4f), 1f - landTime / coreLandDuration); + float fin = landTime / coreLandDuration; + if(!launching) fin = 1f - fin; + camerascale = landInterp.apply(minZoomScl, Scl.scl(4f), fin); weatherAlpha = 0f; //snap camera to cutscene core regardless of player input @@ -312,7 +314,8 @@ public class Renderer implements ApplicationListener{ } void updateLandParticles(){ - float tsize = Mathf.sample(thrusterSize, (landTime + 35f) / coreLandDuration); + float time = launching ? coreLandDuration - landTime : landTime; + float tsize = Mathf.sample(thrusterSizes, (time + 35f) / coreLandDuration); landPTimer += tsize * Time.delta; if(landCore != null && landPTimer >= 1f){ @@ -331,9 +334,12 @@ public class Renderer implements ApplicationListener{ var clouds = assets.get("sprites/clouds.png", Texture.class); if(landTime > 0 && build != null){ float fout = landTime / coreLandDuration; + + if(launching) fout = 1f - fout; + float fin = 1f - fout; - //core + //draw core var block = (CoreBlock)build.block; TextureRegion reg = block.fullIcon; float scl = Scl.scl(4f) / camerascale; @@ -341,7 +347,15 @@ public class Renderer implements ApplicationListener{ float s = reg.width * Draw.scl * scl * 3.6f * Interp.pow2Out.apply(fout); float rotation = Interp.pow2In.apply(fout) * 135f, x = build.x + Mathf.range(shake), y = build.y + Mathf.range(shake); float thrustOpen = 0.25f; - float frame = fin >= thrustOpen ? 1f : fin / thrustOpen; + float thrusterFrame = fin >= thrustOpen ? 1f : fin / thrustOpen; + float thrusterSize = Mathf.sample(thrusterSizes, fin); + + //when launching, thrusters stay out the entire time. + if(launching){ + Interp i = Interp.pow2Out; + thrusterFrame = i.apply(Mathf.clamp(fout*13f)); + thrusterSize = i.apply(Mathf.clamp(fout*9f)); + } Draw.color(Pal.lightTrail); //TODO spikier heat @@ -351,20 +365,20 @@ public class Renderer implements ApplicationListener{ float pfin = Interp.pow3Out.apply(fin), pf = Interp.pow2In.apply(fout); - //particles + //draw particles Angles.randLenVectors(1, pfin, 100, 800f * scl * pfin, (ax, ay, ffin, ffout) -> { Lines.stroke(scl * ffin * pf * 3f); Lines.lineAngle(build.x + ax, build.y + ay, Mathf.angle(ax, ay), (ffin * 20 + 1f) * scl); }); Draw.color(); - Draw.mixcol(Color.white, Interp.pow2In.apply(fout)); + Draw.mixcol(Color.white, Interp.pow5In.apply(fout)); Draw.scl(scl); Draw.alpha(1f); - //thruster flame - float strength = (1f + (block.size - 3)/2.5f) * scl * Mathf.sample(thrusterSize, fin) * (0.95f + Mathf.absin(2f, 0.1f)); + //draw thruster flame + float strength = (1f + (block.size - 3)/2.5f) * scl * thrusterSize * (0.95f + Mathf.absin(2f, 0.1f)); float offset = (block.size - 3) * 3f * scl; for(int i = 0; i < 4; i++){ @@ -379,12 +393,12 @@ public class Renderer implements ApplicationListener{ Fill.circle(Tmp.v1.x + x, Tmp.v1.y + y, 3.5f * strength); } - drawThrusters(block, x, y, rotation, frame); + drawThrusters(block, x, y, rotation, thrusterFrame); Drawf.spinSprite(block.region, x, y, rotation); - Draw.alpha(Interp.pow4In.apply(frame)); - drawThrusters(block, x, y, rotation, frame); + Draw.alpha(Interp.pow4In.apply(thrusterFrame)); + drawThrusters(block, x, y, rotation, thrusterFrame); Draw.alpha(1f); Drawf.spinSprite(block.teamRegions[build.team.id], x, y, rotation); @@ -393,8 +407,8 @@ public class Renderer implements ApplicationListener{ Draw.reset(); + //draw clouds if(state.rules.cloudColor.a > 0.0001f){ - //clouds float scaling = cloudScaling; float sscl = Math.max(1f + Mathf.clamp(fin + cfinOffset)* cfinScl, 0f) * camerascale; @@ -472,16 +486,18 @@ public class Renderer implements ApplicationListener{ } public void showLanding(){ - isLaunching = false; + launching = false; camerascale = minZoomScl; landTime = coreLandDuration; cloudSeed = Mathf.random(1f); } public void showLaunch(){ - isLaunching = true; + Vars.ui.hudfrag.showLaunch(); + launching = true; landCore = player.team().core(); cloudSeed = Mathf.random(1f); + landTime = coreLandDuration; //TODO other stuff. } diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index 946d1effc3..74d0265058 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -913,6 +913,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ }else{ CoreBlock block = from.info.bestCoreType instanceof CoreBlock b ? b : (CoreBlock)Blocks.coreShard; + //TODO load launchFrom sector right before launching so animation is correct loadouts.show(block, from, () -> { from.removeItems(universe.getLastLoadout().requirements()); from.removeItems(universe.getLaunchResources()); @@ -923,7 +924,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ //TODO renderer.showLaunch(); hide(); - Time.runTask(launchDuration, () -> control.playSector(from, sector)); + //run with less delay, as the loading animation is delayed by several frames + Time.runTask(coreLandDuration - 8f, () -> control.playSector(from, sector)); }); } }else if(mode == select){ diff --git a/core/src/mindustry/ui/fragments/HudFragment.java b/core/src/mindustry/ui/fragments/HudFragment.java index 49b262aaa0..5fc4654cd2 100644 --- a/core/src/mindustry/ui/fragments/HudFragment.java +++ b/core/src/mindustry/ui/fragments/HudFragment.java @@ -545,11 +545,21 @@ public class HudFragment extends Fragment{ } } - public void showLaunchDirect(){ + public void showLaunch(){ + float margin = 30f; + Image image = new Image(); image.color.a = 0f; + image.touchable = Touchable.disabled; image.setFillParent(true); - image.actions(Actions.fadeIn(launchDuration / 60f, Interp.pow2In), Actions.delay(8f / 60f), Actions.remove()); + image.actions(Actions.delay((coreLandDuration - margin) / 60f), Actions.fadeIn(margin / 60f, Interp.pow2In), Actions.delay(6f / 60f), Actions.remove()); + image.update(() -> { + image.toFront(); + ui.loadfrag.toFront(); + if(state.isMenu()){ + image.remove(); + } + }); Core.scene.add(image); } @@ -558,9 +568,10 @@ public class HudFragment extends Fragment{ image.color.a = 1f; image.touchable = Touchable.disabled; image.setFillParent(true); - image.actions(Actions.fadeOut(0.8f), Actions.remove()); + image.actions(Actions.fadeOut(35f / 60f), Actions.remove()); image.update(() -> { image.toFront(); + ui.loadfrag.toFront(); if(state.isMenu()){ image.remove(); } diff --git a/core/src/mindustry/ui/fragments/LoadingFragment.java b/core/src/mindustry/ui/fragments/LoadingFragment.java index 348783fe05..902e6ea3ca 100644 --- a/core/src/mindustry/ui/fragments/LoadingFragment.java +++ b/core/src/mindustry/ui/fragments/LoadingFragment.java @@ -45,6 +45,10 @@ public class LoadingFragment extends Fragment{ }); } + public void toFront(){ + table.toFront(); + } + public void setProgress(Floatp progress){ bar.reset(0f); bar.visible = true;