From 68f1efdbdd5ab577851bbd7237c3e302daf9e27b Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 1 Jun 2020 16:00:36 -0400 Subject: [PATCH] Sector launch impl --- .../graphics/g3d/PlanetRenderer.java | 106 ++++------- core/src/mindustry/type/Planet.java | 5 +- core/src/mindustry/type/Sector.java | 3 +- core/src/mindustry/type/Weapon.java | 2 +- .../mindustry/ui/dialogs/PlanetDialog.java | 177 ++++++++++++++---- gradle.properties | 2 +- 6 files changed, 182 insertions(+), 113 deletions(-) diff --git a/core/src/mindustry/graphics/g3d/PlanetRenderer.java b/core/src/mindustry/graphics/g3d/PlanetRenderer.java index cd87079594..e148254139 100644 --- a/core/src/mindustry/graphics/g3d/PlanetRenderer.java +++ b/core/src/mindustry/graphics/g3d/PlanetRenderer.java @@ -8,17 +8,11 @@ import arc.graphics.gl.*; import arc.math.*; import arc.math.geom.*; import arc.struct.*; -import arc.util.ArcAnnotate.*; import arc.util.*; import mindustry.content.*; -import mindustry.game.Objectives.*; -import mindustry.game.*; -import mindustry.gen.*; import mindustry.graphics.*; import mindustry.graphics.g3d.PlanetGrid.*; import mindustry.type.*; -import mindustry.type.Sector.*; -import mindustry.ui.*; public class PlanetRenderer implements Disposable{ public static final float outlineRad = 1.17f, camLength = 4f; @@ -29,6 +23,10 @@ public class PlanetRenderer implements Disposable{ shadowColor = new Color(0, 0, 0, 0.7f); private static final Array points = new Array<>(); + private static final PlanetInterfaceRenderer emptyRenderer = new PlanetInterfaceRenderer(){ + @Override public void renderSectors(Planet planet){} + @Override public void renderProjections(){} + }; /** Camera direction relative to the planet. Length is determined by zoom. */ public final Vec3 camPos = new Vec3(); @@ -38,15 +36,16 @@ public class PlanetRenderer implements Disposable{ public Planet planet = Planets.starter; /** Camera used for rendering. */ public Camera3D cam = new Camera3D(); + /** Raw vertex batch. */ + public final VertexBatch3D batch = new VertexBatch3D(10000, false, true, 0); - public float zoom = 1f, selectAlpha = 1f; - public @Nullable Sector selected, hovered; + public float zoom = 1f; private final Mesh[] outlines = new Mesh[10]; - private final VertexBatch3D batch = new VertexBatch3D(10000, false, true, 0); private final PlaneBatch3D projector = new PlaneBatch3D(); private final Mat3D mat = new Mat3D(); private final FrameBuffer buffer = new FrameBuffer(2, 2, true); + private PlanetInterfaceRenderer irenderer; private final Bloom bloom = new Bloom(Core.graphics.getWidth()/4, Core.graphics.getHeight()/4, true, false){{ setThreshold(0.8f); @@ -64,7 +63,9 @@ public class PlanetRenderer implements Disposable{ } /** Render the entire planet scene to the screen. */ - public void render(){ + public void render(PlanetInterfaceRenderer irenderer){ + this.irenderer = irenderer; + Draw.flush(); Gl.clear(Gl.depthBufferBit); Gl.enable(Gl.depthTest); @@ -95,21 +96,7 @@ public class PlanetRenderer implements Disposable{ Gl.enable(Gl.blend); - //TODO perhaps draw this somewhere else - if(hovered != null){ - Draw.batch(projector, () -> { - setPlane(hovered); - Draw.color(Color.white, Pal.accent, Mathf.absin(5f, 1f)); - - TextureRegion icon = hovered.locked() ? Icon.lock.getRegion() : hovered.is(SectorAttribute.naval) ? Liquids.water.icon(Cicon.large) : null; - - if(icon != null){ - Draw.rect(icon, 0, 0); - } - - Draw.reset(); - }); - } + irenderer.renderProjections(); Gl.disable(Gl.cullFace); Gl.disable(Gl.depthTest); @@ -168,46 +155,7 @@ public class PlanetRenderer implements Disposable{ //apply transformed position batch.proj().mul(planet.getTransform(mat)); - for(Sector sec : planet.sectors){ - - if(selectAlpha > 0.01f){ - if(sec.unlocked()){ - Color color = - sec.hasBase() ? Team.sharded.color : - sec.preset != null ? Team.derelict.color : - sec.hasEnemyBase() ? Team.crux.color : - null; - - if(color != null){ - drawSelection(sec, Tmp.c1.set(color).mul(0.8f).a(selectAlpha), 0.026f, -0.001f); - } - }else{ - draw(sec, Tmp.c1.set(shadowColor).mul(1, 1, 1, selectAlpha), -0.001f); - } - } - } - - if(hovered != null){ - draw(hovered, hoverColor, -0.001f); - drawBorders(hovered, borderColor); - } - - if(selected != null){ - drawSelection(selected); - drawBorders(selected, borderColor); - } - - batch.flush(Gl.triangles); - - //render arcs - if(selected != null && selected.preset != null){ - for(Objective o : selected.preset.requirements){ - if(o instanceof SectorObjective){ - SectorPreset preset = ((SectorObjective)o).preset; - drawArc(planet, selected.tile.v, preset.sector.tile.v); - } - } - } + irenderer.renderSectors(planet); //render sector grid Mesh mesh = outline(planet.grid.size); @@ -222,12 +170,12 @@ public class PlanetRenderer implements Disposable{ mesh.render(shader, Gl.lines); } - private void drawArc(Planet planet, Vec3 a, Vec3 b){ - Vec3 avg = Tmp.v31.set(a).add(b).scl(0.5f); + public void drawArc(Planet planet, Vec3 a, Vec3 b){ + Vec3 avg = Tmp.v31.set(b).add(a).scl(0.5f); avg.setLength(planet.radius*2f); points.clear(); - points.addAll(Tmp.v33.set(a).setLength(outlineRad), Tmp.v31, Tmp.v34.set(b).setLength(outlineRad)); + points.addAll(Tmp.v33.set(b).setLength(outlineRad), Tmp.v31, Tmp.v34.set(a).setLength(outlineRad)); Tmp.bz3.set(points); float points = 25; @@ -241,7 +189,7 @@ public class PlanetRenderer implements Disposable{ batch.flush(Gl.lineStrip); } - private void drawBorders(Sector sector, Color base){ + public void drawBorders(Sector sector, Color base){ Color color = Tmp.c1.set(base).a(base.a + 0.3f + Mathf.absin(Time.globalTime(), 5f, 0.3f)); float r1 = 1f; @@ -268,7 +216,14 @@ public class PlanetRenderer implements Disposable{ } } - private void setPlane(Sector sector){ + public void drawPlane(Sector sector, Runnable run){ + Draw.batch(projector, () -> { + setPlane(sector); + run.run(); + }); + } + + public void setPlane(Sector sector){ float rotation = -planet.getRotation(); float length = 0.01f; @@ -282,7 +237,7 @@ public class PlanetRenderer implements Disposable{ ); } - private void draw(Sector sector, Color color, float offset){ + public void fill(Sector sector, Color color, float offset){ float rr = outlineRad + offset; for(int i = 0; i < sector.tile.corners.length; i++){ Corner c = sector.tile.corners[i], next = sector.tile.corners[(i+1) % sector.tile.corners.length]; @@ -290,11 +245,11 @@ public class PlanetRenderer implements Disposable{ } } - private void drawSelection(Sector sector){ + public void drawSelection(Sector sector){ drawSelection(sector, Pal.accent, 0.04f, 0.001f); } - private void drawSelection(Sector sector, Color color, float stroke, float length){ + public void drawSelection(Sector sector, Color color, float stroke, float length){ float arad = outlineRad + length; for(int i = 0; i < sector.tile.corners.length; i++){ @@ -348,4 +303,9 @@ public class PlanetRenderer implements Disposable{ } } } + + public interface PlanetInterfaceRenderer{ + void renderSectors(Planet planet); + void renderProjections(); + } } diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java index e2f9cab47c..c3d13fe62b 100644 --- a/core/src/mindustry/type/Planet.java +++ b/core/src/mindustry/type/Planet.java @@ -45,6 +45,8 @@ public class Planet extends UnlockableContent{ public float orbitTime; /** Time for the planet to perform a full revolution, in seconds. One day. */ public float rotateTime = 24f * 60f; + /** Approx. radius of one sector. */ + public float sectorApproxRadius; /** Whether this planet is tidally locked relative to its parent - see https://en.wikipedia.org/wiki/Tidal_locking */ public boolean tidalLock = false; /** Whether the bloom render effect is enabled. */ @@ -80,6 +82,8 @@ public class Planet extends UnlockableContent{ sectors.add(new Sector(this, grid.tiles[i], new SectorData())); } + sectorApproxRadius = sectors.first().tile.v.dst(sectors.first().tile.corners[0].v); + //read data for sectors Fi data = Vars.tree.get("planets/" + name + ".dat"); if(data.exists()){ @@ -96,7 +100,6 @@ public class Planet extends UnlockableContent{ } for(Sector sector : sectors){ - sector.unlocked = true; sector.generate(); } }else{ diff --git a/core/src/mindustry/type/Sector.java b/core/src/mindustry/type/Sector.java index ca5b4dd183..14baf187f9 100644 --- a/core/src/mindustry/type/Sector.java +++ b/core/src/mindustry/type/Sector.java @@ -26,7 +26,6 @@ public class Sector{ public @Nullable SaveSlot save; public @Nullable SectorPreset preset; - public boolean unlocked; /** Sector enemy hostility from 0 to 1 */ public float hostility; @@ -47,7 +46,7 @@ public class Sector{ * Only sectors adjacent to non-wave sectors can be landed on. * TODO also preset sectors*/ public boolean unlocked(){ - return Structs.contains(tile.tiles, p -> planet.getSector(p).isCaptured()) || (preset != null && preset.unlocked()); + return hasBase() || Structs.contains(tile.tiles, p -> planet.getSector(p).isCaptured()) || (preset != null && preset.unlocked()); } /** @return whether the player has a base here. */ diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index a73ab597ef..1dde54513f 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -47,7 +47,7 @@ public class Weapon{ /** delay in ticks between shots */ public float shotDelay = 0; /** The half-radius of the cone in which shooting will start. */ - public float shootCone = 1.5f; + public float shootCone = 5f; /** whether shooter rotation is ignored when shooting. */ public boolean ignoreRotation = false; /** sound used for shooting */ diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index dbc8666cbc..27bdc86c23 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -11,22 +11,31 @@ import arc.scene.event.*; import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.util.*; +import arc.util.ArcAnnotate.*; +import mindustry.content.*; import mindustry.ctype.*; +import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.graphics.g3d.*; +import mindustry.graphics.g3d.PlanetRenderer.*; import mindustry.type.*; import mindustry.type.Sector.*; import mindustry.ui.*; import static mindustry.Vars.*; +import static mindustry.graphics.g3d.PlanetRenderer.*; +import static mindustry.ui.dialogs.PlanetDialog.Mode.*; -public class PlanetDialog extends BaseDialog{ +public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ private final FrameBuffer buffer = new FrameBuffer(2, 2, true); private final PlanetRenderer planets = renderer.planets; + private final Table stable = new Table().background(Styles.black3); - private float zoom = 1f; - private Table stable; + private int launchRange; + private float zoom = 1f, selectAlpha = 1f; + private @Nullable Sector selected, hovered, launchSector; + private Mode mode = look; public PlanetDialog(){ super("", Styles.fullDialog); @@ -66,43 +75,128 @@ public class PlanetDialog extends BaseDialog{ addListener(new ElementGestureListener(){ @Override public void tap(InputEvent event, float x, float y, int count, KeyCode button){ - planets.selected = planets.hovered != null && planets.hovered.locked() ? null : planets.hovered; - if(planets.selected != null){ + if(hovered != null && (mode == launch ? canLaunch(hovered) && hovered != launchSector : hovered.unlocked())){ + selected = hovered; + } + + if(selected != null){ updateSelected(); } } }); - stable = new Table(); - stable.background(Styles.black3); - shown(this::setup); } /** show with no limitations, just as a map. */ @Override public Dialog show(){ - //TODO + mode = look; + selected = hovered = launchSector = null; return super.show(); } - public void show(Sector selected, int range){ - planets.selected = null; - planets.hovered = null; + public void show(Sector sector, int range){ + selected = null; + hovered = null; //update view to sector - planets.camPos.set(Tmp.v33.set(selected.tile.v).rotate(Vec3.Y, -selected.planet.getRotation())); - zoom = planets.zoom = 1f; + planets.camPos.set(Tmp.v33.set(sector.tile.v).rotate(Vec3.Y, -sector.planet.getRotation())); + zoom = 1f; + planets.zoom = 2f; + selectAlpha = 0f; + launchRange = range; + launchSector = sector; - show(); - //TODO + mode = launch; + + super.show(); + } + + boolean canLaunch(Sector sector){ + return mode == launch && sector.tile.v.within(launchSector.tile.v, (launchRange + 0.5f) * planets.planet.sectorApproxRadius*2); + } + + @Override + public void renderSectors(Planet planet){ + + //draw all sector stuff + for(Sector sec : planet.sectors){ + if(selectAlpha > 0.01f){ + if(canLaunch(sec) || sec.unlocked()){ + Color color = + sec.hasBase() ? Team.sharded.color : + sec.preset != null ? Team.derelict.color : + sec.hasEnemyBase() ? Team.crux.color : + null; + + if(color != null){ + planets.drawSelection(sec, Tmp.c1.set(color).mul(0.8f).a(selectAlpha), 0.026f, -0.001f); + } + }else{ + planets.fill(sec, Tmp.c1.set(shadowColor).mul(1, 1, 1, selectAlpha), -0.001f); + } + } + } + + if(launchSector != null){ + planets.fill(launchSector, hoverColor, -0.001f); + } + + //draw hover border + if(hovered != null){ + planets.fill(hovered, hoverColor, -0.001f); + planets.drawBorders(hovered, borderColor); + } + + //draw selected borders + if(selected != null){ + planets.drawSelection(selected); + planets.drawBorders(selected, borderColor); + } + + planets.batch.flush(Gl.triangles); + + if(mode == launch){ + if(hovered != launchSector && hovered != null && canLaunch(hovered)){ + planets.drawArc(planet, launchSector.tile.v, hovered.tile.v); + } + } + + /* + //TODO render arcs + if(selected != null && selected.preset != null){ + for(Objective o : selected.preset.requirements){ + if(o instanceof SectorObjective){ + SectorPreset preset = ((SectorObjective)o).preset; + planets.drawArc(planet, selected.tile.v, preset.sector.tile.v); + } + } + }*/ + } + + @Override + public void renderProjections(){ + if(hovered != null){ + planets.drawPlane(hovered, () -> { + Draw.color(Color.white, Pal.accent, Mathf.absin(5f, 1f)); + + TextureRegion icon = hovered.locked() && !canLaunch(hovered) ? Icon.lock.getRegion() : hovered.is(SectorAttribute.naval) ? Liquids.water.icon(Cicon.large) : null; + + if(icon != null){ + Draw.rect(icon, 0, 0); + } + + Draw.reset(); + }); + } } void setup(){ cont.clear(); titleTable.remove(); - cont.rect((x, y, w, h) -> planets.render()).grow(); + cont.rect((x, y, w, h) -> planets.render(this)).grow(); } @Override @@ -128,9 +222,9 @@ public class PlanetDialog extends BaseDialog{ public void act(float delta){ super.act(delta); - if(planets.selected != null){ + if(selected != null){ addChild(stable); - Vec3 pos = planets.cam.project(Tmp.v31.set(planets.selected.tile.v).setLength(PlanetRenderer.outlineRad).rotate(Vec3.Y, -planets.planet.getRotation()).add(planets.planet.position)); + Vec3 pos = planets.cam.project(Tmp.v31.set(selected.tile.v).setLength(PlanetRenderer.outlineRad).rotate(Vec3.Y, -planets.planet.getRotation()).add(planets.planet.position)); stable.setPosition(pos.x, pos.y, Align.center); stable.toFront(); }else{ @@ -138,18 +232,23 @@ public class PlanetDialog extends BaseDialog{ } if(planets.planet.isLandable()){ - planets.hovered = planets.planet.getSector(planets.cam.getMouseRay(), PlanetRenderer.outlineRad); + hovered = planets.planet.getSector(planets.cam.getMouseRay(), PlanetRenderer.outlineRad); }else{ - planets.hovered = planets.selected = null; + hovered = selected = null; } planets.zoom = Mathf.lerpDelta(planets.zoom, zoom, 0.4f); - planets.selectAlpha = Mathf.lerpDelta(planets.selectAlpha, Mathf.num(planets.zoom < 1.9f), 0.1f); + selectAlpha = Mathf.lerpDelta(selectAlpha, Mathf.num(planets.zoom < 1.9f), 0.1f); } //TODO add strings to bundle after prototyping is done private void updateSelected(){ - Sector sector = planets.selected; + Sector sector = selected; + + if(sector == null){ + stable.remove(); + return; + } float x = stable.getX(Align.center), y = stable.getY(Align.center); stable.clear(); @@ -207,7 +306,6 @@ public class PlanetDialog extends BaseDialog{ } }); - }).row(); } @@ -220,31 +318,40 @@ public class PlanetDialog extends BaseDialog{ stable.row(); - stable.button("Launch", Styles.transt, () -> { - if(sector.is(SectorAttribute.naval)){ - ui.showInfo("You need a naval loadout to launch here."); - return; - } - control.playSector(sector); - hide(); - }).growX().padTop(2f).height(50f).minWidth(170f); + if((sector.hasBase() && mode == look) || canLaunch(sector)){ + stable.button(sector.hasBase() ? "Resume" : "Launch", Styles.transt, () -> { + if(sector.is(SectorAttribute.naval)){ + ui.showInfo("You need a naval loadout to launch here."); + return; + } + control.playSector(sector); + hide(); + }).growX().padTop(2f).height(50f).minWidth(170f); + } stable.pack(); stable.setPosition(x, y, Align.center); stable.update(() -> { - if(planets.selected != null){ + if(selected != null){ //fade out UI when not facing selected sector - Tmp.v31.set(planets.selected.tile.v).rotate(Vec3.Y, -planets.planet.getRotation()).scl(-1f).nor(); + Tmp.v31.set(selected.tile.v).rotate(Vec3.Y, -planets.planet.getRotation()).scl(-1f).nor(); float dot = planets.cam.direction.dot(Tmp.v31); stable.getColor().a = Math.max(dot, 0f)*2f; if(dot*2f <= -0.1f){ stable.remove(); - planets.selected = null; + selected = null; } } }); stable.act(0f); } + + enum Mode{ + /** Look around for existing sectors. Can only deploy. */ + look, + /** Launch to a new location. */ + launch + } } diff --git a/gradle.properties b/gradle.properties index 77fffb76a5..010e2b86bb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=8ae9a1cd46776f886d41b483c331e38c9ca96bcf +archash=bab296ea45aeb5863db29b9c64b11c6a2685b619