diff --git a/core/src/mindustry/maps/generators/PlanetGenerator.java b/core/src/mindustry/maps/generators/PlanetGenerator.java index 59783db265..20b90590f2 100644 --- a/core/src/mindustry/maps/generators/PlanetGenerator.java +++ b/core/src/mindustry/maps/generators/PlanetGenerator.java @@ -54,6 +54,25 @@ public abstract class PlanetGenerator extends BasicGenerator implements HexMeshe return sector.planet.allowLaunchToNumbered && (sector.hasBase() || sector.near().contains(Sector::hasBase)); } + public Sector findLaunchCandidate(Sector destination, Sector selected){ + Sector launchSector = selected != null && selected.planet == destination.planet && selected.hasBase() ? selected: null; + //directly nearby. + if(destination.near().contains(launchSector)) return launchSector; + + Sector launchFrom = launchSector; + if(launchFrom == null || (destination.preset == null && !destination.near().contains(launchSector))){ + //TODO pick one with the most resources + launchFrom = destination.near().find(Sector::hasBase); + if(launchFrom == null && destination.preset != null){ + if(launchSector != null) return launchSector; + launchFrom = destination.planet.sectors.min(s -> !s.hasBase() ? Float.MAX_VALUE : s.tile.v.dst2(destination.tile.v)); + if(!launchFrom.hasBase()) launchFrom = null; + } + } + + return launchFrom; + } + /** @return whether to allow landing on the specified procedural sector */ public boolean allowAcceleratorLanding(Sector sector){ return sector.planet.allowLaunchToNumbered; diff --git a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java index 8e0931974e..f037c56768 100644 --- a/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/SerpuloPlanetGenerator.java @@ -87,10 +87,26 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{ return true; } + public boolean allowNumberedLaunch(Sector s){ + return s.hasBase() && (s.info.bestCoreType.size >= 4 || s.isBeingPlayed() && state.rules.defaultTeam.cores().contains(b -> b.block.size >= 4)); + } + @Override public boolean allowLanding(Sector sector){ - return sector.planet.allowLaunchToNumbered && (sector.hasBase() || sector.near().contains(s -> s.hasBase() && - (s.info.bestCoreType.size >= 4 || s.isBeingPlayed() && state.rules.defaultTeam.cores().contains(b -> b.block.size >= 4)))); + return sector.planet.allowLaunchToNumbered && (sector.hasBase() || sector.near().contains(this::allowNumberedLaunch)); + } + + @Override + public Sector findLaunchCandidate(Sector destination, Sector selected){ + if(destination.preset == null || !destination.preset.requireUnlock){ + if(selected != null && selected.isNear(destination) && allowNumberedLaunch(selected)){ + return selected; + }else{ + return destination.near().find(this::allowNumberedLaunch); + } + }else{ + return super.findLaunchCandidate(destination, selected); + } } @Override diff --git a/core/src/mindustry/type/Sector.java b/core/src/mindustry/type/Sector.java index fbdab2cd2a..503f39d754 100644 --- a/core/src/mindustry/type/Sector.java +++ b/core/src/mindustry/type/Sector.java @@ -65,6 +65,15 @@ public class Sector{ } } + public boolean isNear(Sector other){ + for(var tile : tile.tiles){ + if(planet.getSector(tile) == other){ + return true; + } + } + return false; + } + /** Displays threat as a formatted string. */ public String displayThreat(){ float step = 0.25f; diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index ddde346b07..d0fb0ac21d 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -418,6 +418,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ return false; } + if(sector.planet.generator == null) return false; + if(sector.hasBase() || sector.id == sector.planet.startSector) return true; //preset sectors can only be selected once unlocked if(sector.preset != null && sector.preset.requireUnlock){ @@ -425,33 +427,13 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ return sector.preset.unlocked() || node == null || node.parent == null || (node.parent.content.unlocked() && (!(node.parent.content instanceof SectorPreset preset) || preset.sector.hasBase())); } - return sector.planet.generator != null ? - //use planet impl when possible - (mode == planetLaunch ? sector.planet.generator.allowAcceleratorLanding(sector) : sector.planet.generator.allowLanding(sector)) : - mode == planetLaunch || sector.hasBase() || sector.near().contains(Sector::hasBase); //near an occupied sector + return mode == planetLaunch ? sector.planet.generator.allowAcceleratorLanding(sector) : sector.planet.generator.allowLanding(sector); } Sector findLauncher(Sector to){ - if(mode == planetLaunch){ - return launchSector; - } + if(mode == planetLaunch || to.planet.generator == null) return launchSector; - Sector launchSector = this.launchSector != null && this.launchSector.planet == to.planet && this.launchSector.hasBase() ? this.launchSector : null; - //directly nearby. - if(to.near().contains(launchSector)) return launchSector; - - Sector launchFrom = launchSector; - if(launchFrom == null || (to.preset == null && !to.near().contains(launchSector))){ - //TODO pick one with the most resources - launchFrom = to.near().find(Sector::hasBase); - if(launchFrom == null && to.preset != null){ - if(launchSector != null) return launchSector; - launchFrom = state.planet.sectors.min(s -> !s.hasBase() ? Float.MAX_VALUE : s.tile.v.dst2(to.tile.v)); - if(!launchFrom.hasBase()) launchFrom = null; - } - } - - return launchFrom; + return to.planet.generator.findLaunchCandidate(to, launchSector); } boolean showing(){ @@ -484,7 +466,6 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ } Sector hoverOrSelect = hovered != null ? hovered : selected; - Sector launchFrom = hoverOrSelect != null && !hoverOrSelect.hasBase() ? findLauncher(hoverOrSelect) : null; Sector current = Vars.state.getSector() != null && Vars.state.getSector().isBeingPlayed() && Vars.state.getSector().planet == state.planet ? Vars.state.getSector() : null;