diff --git a/core/src/mindustry/content/Planets.java b/core/src/mindustry/content/Planets.java index 6ea9e36773..524c1c1980 100644 --- a/core/src/mindustry/content/Planets.java +++ b/core/src/mindustry/content/Planets.java @@ -1,8 +1,12 @@ package mindustry.content; import arc.graphics.*; +import arc.math.geom.*; +import arc.util.noise.*; import mindustry.ctype.*; +import mindustry.graphics.*; import mindustry.graphics.g3d.*; +import mindustry.graphics.g3d.PlanetGrid.*; import mindustry.maps.planet.*; import mindustry.type.*; @@ -40,8 +44,36 @@ public class Planets implements ContentList{ atmosphereRadIn = 0.02f; atmosphereRadOut = 0.3f; tidalLock = true; + orbitSpacing = 0.5f; + totalRadius += 2.4f; }}; + for(int i = 0; i < 4; i++){ + new Planet("gier-" + i, erekir, 0.1f){{ + hasAtmosphere = false; + alwaysUnlocked = true; + sectors.add(new Sector(this, Ptile.empty)); + camRadius = 0.43f; + + //new SectorPreset(name + "-sector", this, 0){{ + + //}}; + + meshLoader = () -> new HexMesh(this, new HexMesher(){ + Simplex sim = new Simplex(id); + @Override + public float getHeight(Vec3 position){ + return (float)sim.octaveNoise3D(2, 0.6, 0.3f, position.x, position.y, position.z) * 13f; + } + + @Override + public Color getColor(Vec3 position){ + return Pal.gray; + } + }, 2, Shaders.planet); + }}; + } + tantros = new Planet("tantros", sun, 1, 2){{ generator = new TantrosPlanetGenerator(); meshLoader = () -> new HexMesh(this, 4); diff --git a/core/src/mindustry/core/World.java b/core/src/mindustry/core/World.java index 8627230a0f..1c67a5b1b9 100644 --- a/core/src/mindustry/core/World.java +++ b/core/src/mindustry/core/World.java @@ -246,15 +246,17 @@ public class World{ if(sector.preset != null){ sector.preset.generator.generate(tiles); sector.preset.rules.get(state.rules); //apply extra rules - }else{ + }else if(sector.planet.generator != null){ sector.planet.generator.generate(tiles, sector); + }else{ + throw new RuntimeException("Sector " + sector.id + " on planet " + sector.planet.name + " has no generator or preset defined. Provide a planet generator or preset map."); } //just in case state.rules.sector = sector; }); //postgenerate for bases - if(sector.preset == null){ + if(sector.preset == null && sector.planet.generator != null){ sector.planet.generator.postGenerate(tiles); } diff --git a/core/src/mindustry/graphics/g3d/PlanetGrid.java b/core/src/mindustry/graphics/g3d/PlanetGrid.java index 9b72970087..993ca34c25 100644 --- a/core/src/mindustry/graphics/g3d/PlanetGrid.java +++ b/core/src/mindustry/graphics/g3d/PlanetGrid.java @@ -221,6 +221,8 @@ public class PlanetGrid{ } public static class Ptile{ + public static final Ptile empty = new Ptile(0, 0); + public int id; public int edgeCount; diff --git a/core/src/mindustry/graphics/g3d/PlanetRenderer.java b/core/src/mindustry/graphics/g3d/PlanetRenderer.java index 37c38e3833..37dfe36d25 100644 --- a/core/src/mindustry/graphics/g3d/PlanetRenderer.java +++ b/core/src/mindustry/graphics/g3d/PlanetRenderer.java @@ -77,7 +77,7 @@ public class PlanetRenderer implements Disposable{ cam.up.set(Vec3.Y); cam.resize(Core.graphics.getWidth(), Core.graphics.getHeight()); - camPos.setLength(planet.radius * camLength + (zoom-1f) * planet.radius * 2); + camPos.setLength((planet.radius + planet.camRadius) * camLength + (zoom-1f) * (planet.radius + planet.camRadius) * 2); cam.position.set(planet.position).add(camPos); cam.lookAt(planet.position); cam.update(); diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java index ce92bf0ca1..37ec2caa50 100644 --- a/core/src/mindustry/type/Planet.java +++ b/core/src/mindustry/type/Planet.java @@ -17,8 +17,6 @@ import mindustry.maps.generators.*; import static mindustry.Vars.*; public class Planet extends UnlockableContent{ - /** Default spacing between planet orbits in world units. */ - private static final float orbitSpacing = 11f; /** intersect() temp var. */ private static final Vec3 intersectResult = new Vec3(); /** Mesh used for rendering. Created on load() - will be null on the server! */ @@ -31,8 +29,12 @@ public class Planet extends UnlockableContent{ public @Nullable PlanetGenerator generator; /** Array of sectors; directly maps to tiles in the grid. */ public Seq sectors = new Seq<>(); + /** Default spacing between planet orbits in world units. This is defined per-parent! */ + public float orbitSpacing = 11f; /** Radius of this planet's sphere. Does not take into account satellites. */ public float radius; + /** Camera radius offset. */ + public float camRadius; /** Atmosphere radius adjustment parameters. */ public float atmosphereRadIn = 0, atmosphereRadOut = 0.3f; /** Orbital radius around the sun. Do not change unless you know exactly what you are doing.*/ @@ -79,10 +81,10 @@ public class Planet extends UnlockableContent{ this.parent = parent; //total radius is initially just the radius - totalRadius += radius; + totalRadius = radius; //get orbit radius by extending past the parent's total radius - orbitRadius = parent == null ? 0f : (parent.totalRadius + orbitSpacing + totalRadius); + orbitRadius = parent == null ? 0f : (parent.totalRadius + parent.orbitSpacing + totalRadius); //orbit time is based on radius [kepler's third law] orbitTime = Mathf.pow(orbitRadius, 1.5f) * 1000; @@ -132,6 +134,11 @@ public class Planet extends UnlockableContent{ return grid != null && generator != null && sectors.size > 0; } + /** @return whether this planet has any sectors to land on. */ + public boolean isLandable(){ + return sectors.size > 0; + } + public void updateTotalRadius(){ totalRadius = radius; for(Planet planet : children){ diff --git a/core/src/mindustry/type/Sector.java b/core/src/mindustry/type/Sector.java index 7aea305426..a7cc5851c7 100644 --- a/core/src/mindustry/type/Sector.java +++ b/core/src/mindustry/type/Sector.java @@ -39,7 +39,12 @@ public class Sector{ this.planet = planet; this.tile = tile; this.plane = new Plane(); - this.rect = makeRect(); + //empty sector tile needs a special rect + if(tile.corners.length == 0){ + rect = new SectorRect(1f, Vec3.Zero.cpy(), Vec3.Y.cpy(), Vec3.X.cpy(), 0f); + }else{ + this.rect = makeRect(); + } this.id = tile.id; } diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index f9a838b9e1..06e142f233 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -25,6 +25,7 @@ import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.graphics.g3d.*; +import mindustry.graphics.g3d.PlanetGrid.*; import mindustry.input.*; import mindustry.io.legacy.*; import mindustry.maps.*; @@ -277,6 +278,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ } void lookAt(Sector sector){ + if(sector.tile == Ptile.empty) return; + planets.camPos.set(Tmp.v33.set(sector.tile.v).rotate(Vec3.Y, -sector.planet.getRotation())); } @@ -430,7 +433,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ boolean selectable(Planet planet){ //TODO what if any sector is selectable? if(mode == planetLaunch) return launchSector != null && planet != launchSector.planet; - return planet == planets.planet || planet.alwaysUnlocked || planet.sectors.contains(Sector::hasBase); + return planet == planets.planet || (planet.alwaysUnlocked && planet.isLandable()) || planet.sectors.contains(Sector::hasBase); } void setup(){ @@ -543,7 +546,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ public void act(float delta){ super.act(delta); - if(hovered != null && !mobile){ + if(hovered != null && !mobile && planets.planet.hasGrid()){ addChild(hoverLabel); hoverLabel.toFront(); hoverLabel.touchable = Touchable.disabled; @@ -595,6 +598,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ if(planets.planet.hasGrid()){ hovered = planets.planet.getSector(planets.cam.getMouseRay(), PlanetRenderer.outlineRad); + }else if(planets.planet.isLandable()){ + //always have the first sector selected. + //TODO better support for multiple sectors in gridless planets? + hovered = selected = planets.planet.sectors.first(); }else{ hovered = selected = null; }