Finalized launch pad mechanics

This commit is contained in:
Anuken 2025-02-02 18:10:15 -05:00
parent c6d82bec66
commit 7aee34bafa
19 changed files with 310 additions and 52 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -737,6 +737,8 @@ addall = Add All
launch.from = Launching From: [accent]{0}
launch.capacity = Launching Item Capacity: [accent]{0}
launch.destination = Destination: {0}
landing.sources = Source Sectors: [accent]{0}[]
landing.import = Max Total Import: {0}[accent]{1}[lightgray]/min
configure.invalid = Amount must be a number between 0 and {0}.
add = Add...
guardian = Guardian
@ -778,6 +780,7 @@ sectors.launch = Launch
sectors.select = Select
sectors.launchselect = Select Launch Destination
sectors.nonelaunch = [lightgray]none (sun)
sectors.redirect = Redirect Launch Pads
sectors.rename = Rename Sector
sectors.enemybase = [scarlet]Enemy Base
sectors.vulnerable = [scarlet]Vulnerable
@ -1748,7 +1751,10 @@ block.spectre.name = Spectre
block.meltdown.name = Meltdown
block.foreshadow.name = Foreshadow
block.container.name = Container
block.launch-pad.name = Launch Pad (Legacy)
block.launch-pad.name = Launch Pad [lightgray](Legacy)
block.advanced-launch-pad.name = Launch Pad
block.landing-pad.name = Landing Pad
block.segment.name = Segment
block.ground-factory.name = Ground Factory
block.air-factory.name = Air Factory
@ -2198,7 +2204,9 @@ block.vault.description = Stores a large amount of items of each type. Expands s
block.container.description = Stores a small amount of items of each type. Expands storage when placed next to a core. Contents can be retrieved with an unloader.
block.unloader.description = Unloads the selected item from nearby blocks.
block.launch-pad.description = Launches batches of items to selected sectors.
block.launch-pad.details = Sub-orbital system for point-to-point transportation of resources. Payload pods are fragile and incapable of surviving re-entry.
block.advanced-launch-pad.description = Launches batches of items to selected sectors. Only accepts one item type at a time.
block.advanced-launch-pad.details = Sub-orbital system for point-to-point transportation of resources.
block.landing-pad.description = Receives items from launch pads in other sectors. Requires large amounts of water to protect against impacts of landings.
block.duo.description = Fires alternating bullets at enemies.
block.scatter.description = Fires clumps of lead, scrap or metaglass flak at enemy aircraft.
block.scorch.description = Burns any ground enemies close to it. Highly effective at close range.

View file

@ -595,3 +595,5 @@
63087=scathe-missile-phase|unit-scathe-missile-phase-ui
63086=scathe-missile-surge|unit-scathe-missile-surge-ui
63085=scathe-missile-surge-split|unit-scathe-missile-surge-split-ui
63084=advanced-launch-pad|block-advanced-launch-pad-ui
63083=landing-pad|block-landing-pad-ui

Binary file not shown.

View file

@ -6364,23 +6364,26 @@ public class Blocks{
}};
advancedLaunchPad = new LaunchPad("advanced-launch-pad"){{
requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.copper, 350, Items.silicon, 140, Items.lead, 200, Items.titanium, 150));
requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.copper, 350, Items.silicon, 250, Items.lead, 300, Items.titanium, 200));
size = 4;
itemCapacity = 100;
launchTime = 60f * 30;
liquidCapacity = 40f;
hasPower = true;
drawLiquid = Liquids.oil;
consumeLiquid(Liquids.oil, 9f/60f);
consumePower(8f);
}};
landingPad = new LandingPad("landing-pad"){{
requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.copper, 350, Items.silicon, 140, Items.lead, 200, Items.titanium, 150));
requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.copper, 300, Items.graphite, 200, Items.titanium, 150));
size = 4;
itemCapacity = 100;
liquidCapacity = 4000f;
consumeLiquidAmount = 2000f;
coolingEffect = new RadialEffect(Fx.steamCoolSmoke, 4, 90f, 9.5f, 180f);
liquidCapacity = 5000f;
consumeLiquidAmount = 2500f;
}};
interplanetaryAccelerator = new Accelerator("interplanetary-accelerator"){{

View file

@ -1474,6 +1474,12 @@ public class Fx{
Lines.circle(e.x, e.y, e.fin() * (e.rotation + 50f));
}),
podLandShockwave = new Effect(12f, 80f, e -> {
color(Pal.accent);
stroke(e.fout() * 2f + 0.2f);
Lines.circle(e.x, e.y, e.fin() * 26f);
}),
explosion = new Effect(30, e -> {
e.scaled(7, i -> {
stroke(3f * i.fout());
@ -1624,6 +1630,15 @@ public class Fx{
});
}),
steamCoolSmoke = new Effect(35f, e -> {
color(Pal.water, Color.lightGray, e.fin(Interp.pow2Out));
alpha(e.fout(Interp.pow3Out));
randLenVectors(e.id, 4, e.finpow() * 7f, e.rotation, 30f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, Math.max(e.fout(), Math.min(1f, e.fin() * 8f)) * 2.8f);
});
}),
smokePuff = new Effect(30, e -> {
color(e.color);
@ -2574,6 +2589,13 @@ public class Fx{
Fill.circle(e.x + Tmp.v1.x, e.y + Tmp.v1.y, 8f * rand.random(0.6f, 1f) * e.fout(0.2f));
}).layer(Layer.groundUnit + 1f),
podLandDust = new Effect(70f, e -> {
color(e.color, e.fout(0.1f));
rand.setSeed(e.id);
Tmp.v1.trns(e.rotation, e.finpow() * 35f * rand.random(0.2f, 1f));
Fill.circle(e.x + Tmp.v1.x, e.y + Tmp.v1.y, 5f * rand.random(0.6f, 1f) * e.fout(0.2f));
}).layer(Layer.groundUnit + 1f),
unitShieldBreak = new Effect(35, e -> {
if(!(e.data instanceof Unit unit)) return;

View file

@ -20,8 +20,10 @@ public class SerpuloTechTree{
node(junction, () -> {
node(router, () -> {
node(advancedLaunchPad, Seq.with(new SectorComplete(extractionOutpost)), () -> {
node(interplanetaryAccelerator, Seq.with(new SectorComplete(planetaryTerminal)), () -> {
node(landingPad, () -> {
node(interplanetaryAccelerator, Seq.with(new SectorComplete(planetaryTerminal)), () -> {
});
});
});

View file

@ -8,7 +8,7 @@ import mindustry.entities.*;
/** Renders one particle effect repeatedly at specified angle intervals. */
public class RadialEffect extends Effect{
public Effect effect = Fx.none;
public float rotationSpacing = 90f, rotationOffset = 0f;
public float rotationSpacing = 90f, rotationOffset = 0f, effectRotationOffset = 0f;
public float lengthOffset = 0f;
public int amount = 4;
@ -16,14 +16,19 @@ public class RadialEffect extends Effect{
clip = 100f;
}
public RadialEffect(Effect effect, int amount, float spacing, float lengthOffset){
public RadialEffect(Effect effect, int amount, float spacing, float lengthOffset, float effectRotationOffset){
this();
this.amount = amount;
this.effect = effect;
this.effectRotationOffset = effectRotationOffset;
this.rotationSpacing = spacing;
this.lengthOffset = lengthOffset;
}
public RadialEffect(Effect effect, int amount, float spacing, float lengthOffset){
this(effect, amount, spacing, lengthOffset, 0f);
}
@Override
public void create(float x, float y, float rotation, Color color, Object data){
if(!shouldCreate()) return;
@ -31,7 +36,7 @@ public class RadialEffect extends Effect{
rotation += rotationOffset;
for(int i = 0; i < amount; i++){
effect.create(x + Angles.trnsx(rotation, lengthOffset), y + Angles.trnsy(rotation, lengthOffset), rotation, color, data);
effect.create(x + Angles.trnsx(rotation, lengthOffset), y + Angles.trnsy(rotation, lengthOffset), rotation + effectRotationOffset, color, data);
rotation += rotationSpacing;
}
}

View file

@ -30,6 +30,9 @@ public class SectorInfo{
public ObjectMap<Item, ExportStat> rawProduction = new ObjectMap<>();
/** Export statistics. */
public ObjectMap<Item, ExportStat> export = new ObjectMap<>();
//TODO: there is an obvious exploit with launch pad redirection here; pads can be redirected after leaving a sector, which doesn't update calculations.
/** Import statistics, based on what launch pads are actually receiving. TODO: this is not actually used or displayed anywhere (yet) */
public ObjectMap<Item, ExportStat> imports = new ObjectMap<>();
/** Items stored in all cores. */
public ItemSeq items = new ItemSeq();
/** The best available core type. */
@ -118,10 +121,20 @@ public class SectorInfo{
export.get(item, ExportStat::new).counter += amount;
}
/** Updates import statistics. */
public void handleItemImport(Item item, int amount){
imports.get(item, ExportStat::new).counter += amount;
}
public float getExport(Item item){
return export.get(item, ExportStat::new).mean;
}
public boolean hasExport(Item item){
var exp = export.get(item);
return exp != null && exp.mean > 0f;
}
public void refreshImportRates(Planet planet){
if(importRateCache == null || importRateCache.length != content.items().size){
importRateCache = new float[content.items().size];
@ -140,7 +153,7 @@ public class SectorInfo{
return importRateCache;
}
/** @return the import rate of an item as item/second. */
/** @return the import rate of an item as item/second. This is the *raw* max import rate, not what landing pads are actually using. */
public float getImportRate(Planet planet, Item item){
return getImportRates(planet)[item.id];
}
@ -239,19 +252,8 @@ public class SectorInfo{
//refresh throughput
if(time.get(refreshPeriod)){
//refresh export
export.each((item, stat) -> {
//initialize stat after loading
if(!stat.loaded){
stat.means.fill(stat.mean);
stat.loaded = true;
}
//add counter, subtract how many items were taken from the core during this time
stat.means.add(Math.max(stat.counter, 0));
stat.counter = 0;
stat.mean = stat.means.rawMean();
});
updateStats(export);
updateStats(imports);
if(coreDeltas == null) coreDeltas = new int[content.items().size];
if(productionDeltas == null) productionDeltas = new int[content.items().size];
@ -268,6 +270,11 @@ public class SectorInfo{
//export can, at most, be the raw items being produced from factories + the items being taken from the core
export.get(item).mean = Math.min(export.get(item).mean, rawProduction.get(item).mean + Math.max(-production.get(item).mean, 0));
}
if(imports.containsKey(item)){
//import can't exceed max import rate
imports.get(item).mean = Math.min(imports.get(item).mean, getImportRate(state.getPlanet(), item));
}
}
Arrays.fill(coreDeltas, 0);
@ -275,6 +282,20 @@ public class SectorInfo{
}
}
void updateStats(ObjectMap<Item, ExportStat> map){
map.each((item, stat) -> {
//initialize stat after loading
if(!stat.loaded){
stat.means.fill(stat.mean);
stat.loaded = true;
}
stat.means.add(Math.max(stat.counter, 0));
stat.counter = 0;
stat.mean = stat.means.rawMean();
});
}
void updateDelta(Item item, ObjectMap<Item, ExportStat> map, int[] deltas){
ExportStat stat = map.get(item, ExportStat::new);
if(!stat.loaded){

View file

@ -5,6 +5,7 @@ import arc.graphics.*;
public class Pal{
public static Color
water = Color.valueOf("596ab8"),
darkOutline = Color.valueOf("2d2f39"),
thoriumPink = Color.valueOf("f9a3c7"),
coalBlack = Color.valueOf("272727"),

View file

@ -962,7 +962,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
//import
if(sector.hasBase()){
displayItems(c, 1f, sector.info.importStats(sector.planet), "@sectors.import", t -> {
displayItems(c, 1f, sector.info.imports, "@sectors.import", t -> {
sector.info.eachImport(sector.planet, other -> {
String ic = other.iconChar();
t.add(Iconc.rightOpen + " " + (ic == null || ic.isEmpty() ? "" : ic + " ") + other.name()).padLeft(10f).row();

View file

@ -1,6 +1,8 @@
package mindustry.world.blocks.campaign;
import arc.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
@ -8,6 +10,7 @@ import arc.util.*;
import arc.util.io.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.graphics.*;
@ -16,6 +19,7 @@ import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.liquid.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*;
@ -32,10 +36,19 @@ public class LandingPad extends Block{
});
}
public float cooldownTime = 12f;
public @Load(value = "@-pod", fallback = "advanced-launch-pad-pod") TextureRegion podRegion;
public float arrivalDuration = 150f;
public float cooldownTime = 180f;
public float consumeLiquidAmount = 100f;
public Liquid consumeLiquid = Liquids.water;
public Effect landEffect = Fx.podLandShockwave;
public Effect coolingEffect = Fx.none;
public float coolingEffectChance = 0.2f;
public float liquidPad = 2f;
public Color bottomColor = Pal.darkerMetal;
public LandingPad(String name){
super(name);
@ -45,6 +58,8 @@ public class LandingPad extends Block{
update = true;
configurable = true;
acceptsItems = false;
emitLight = true;
lightRadius = 90f;
config(Item.class, (LandingPadBuild build, Item item) -> build.config = item);
configClear((LandingPadBuild build) -> build.config = null);
@ -97,21 +112,19 @@ public class LandingPad extends Block{
public @Nullable Item config;
//priority collisions are possible, but should be extremely rare
public int priority = Mathf.rand.nextInt();
public float cooldown = 0f;
public float cooldown = 0f, landParticleTimer;
public float arrivingTimer = 0f;
public @Nullable Item arriving;
public float liquidRemoved;
public void handleLanding(){
if(!state.isCampaign() || config == null) return;
//TODO animation, etc
cooldown = 1f;
items.set(config, itemCapacity);
liquids.remove(consumeLiquid, consumeLiquidAmount);
for(int i = 0; i < 10; i++){
Fx.steam.at(this);
}
//TODO this is a temporary effect
Fx.shockwave.at(this);
arriving = config;
arrivingTimer = 0f;
liquidRemoved = 0f;
state.rules.sector.info.importCooldownTimers.put(config, 0f);
}
@ -128,6 +141,9 @@ public class LandingPad extends Block{
float framesBetweenArrival = itemCapacity / importedPerFrame;
state.rules.sector.info.importCooldownTimers.increment(item, 0f, 1f / framesBetweenArrival * Time.delta);
}else{
//nothing is being imported, so reset the timer
state.rules.sector.info.importCooldownTimers.put(item, 0f);
}
}
@ -140,32 +156,144 @@ public class LandingPad extends Block{
Call.landingPadLanded(first.tile);
//swap priorities, moving this block to the end of the list (if there is only one block waiting, this does nothing)
var tmp = first.priority;
first.priority = head.priority;
head.priority = tmp;
pads.clear();
}
});
}
}
@Override
public void draw(){
if(consumeLiquid != null){
Draw.color(bottomColor);
Fill.square(x, y, size * tilesize/2f - liquidPad);
Draw.color();
LiquidBlock.drawTiledFrames(block.size, x, y, liquidPad, liquidPad, liquidPad, liquidPad, consumeLiquid, liquids.get(consumeLiquid) / liquidCapacity);
}
super.draw();
if(arriving != null){
float fin = Mathf.clamp(arrivingTimer), fout = 1f - fin;
float alpha = Interp.pow5Out.apply(fin);
float scale = (1f - alpha) * 1.3f + 1f;
float
cx = x,
cy = y + Interp.pow4In.apply(fout) * (100f + Mathf.randomSeedRange(id() + 2, 30f));
float rotation = fout * (90f + Mathf.randomSeedRange(id(), 50f));
Draw.z(Layer.effect + 0.001f);
Draw.color(Pal.engine);
float rad = 0.15f + Interp.pow5Out.apply(Mathf.slope(fin));
Fill.light(cx, cy, 10, 25f * (rad + scale-1f), Tmp.c2.set(Pal.engine).a(alpha), Tmp.c1.set(Pal.engine).a(0f));
Draw.alpha(alpha);
for(int i = 0; i < 4; i++){
Drawf.tri(cx, cy, 6f, 40f * (rad + scale-1f), i * 90f + rotation);
}
Draw.color();
Draw.z(Layer.weather - 1);
scale *= podRegion.scl();
float rw = podRegion.width * scale, rh = podRegion.height * scale;
Draw.alpha(alpha);
Drawf.shadow(cx, cy, size * tilesize, fin);
Draw.rect(podRegion, cx, cy, rw, rh, rotation);
Tmp.v1.trns(225f, Interp.pow3In.apply(fout) * 250f);
Draw.z(Layer.flyingUnit + 1);
Draw.color(0, 0, 0, 0.22f * alpha);
Draw.rect(podRegion, cx + Tmp.v1.x, cy + Tmp.v1.y, rw, rh, rotation);
}else if(cooldown > 0f){
Drawf.shadow(x, y, size * tilesize, cooldown);
Draw.alpha(cooldown);
Draw.mixcol(Pal.accent, 1f - cooldown);
Draw.rect(podRegion, x, y);
}
Draw.reset();
}
@Override
public void drawLight(){
Drawf.light(x, y, lightRadius, Pal.accent, Mathf.clamp(Math.max(cooldown, arrivingTimer * 1.5f)));
}
@Override
public void updateTile(){
updateTimers();
if(arriving != null){
if(!headless){ //pod particles
float fin = arrivingTimer;
float tsize = Interp.pow5Out.apply(fin);
landParticleTimer += tsize * Time.delta / 2f;
if(landParticleTimer >= 1f){
tile.getLinkedTiles(t -> {
if(Mathf.chance(0.1f)){
Fx.podLandDust.at(t.worldx(), t.worldy(), angleTo(t.worldx(), t.worldy()) + Mathf.range(30f), Tmp.c1.set(t.floor().mapColor).mul(1.5f + Mathf.range(0.15f)));
}
});
landParticleTimer = 0f;
}
}
arrivingTimer += Time.delta / arrivalDuration;
float toRemove = Math.min(consumeLiquidAmount / arrivalDuration * Time.delta, consumeLiquidAmount - liquidRemoved);
liquidRemoved += toRemove;
liquids.remove(consumeLiquid, toRemove);
if(Mathf.chanceDelta(coolingEffectChance * Interp.pow5Out.apply(arrivingTimer))){
coolingEffect.at(this);
}
if(arrivingTimer >= 1f){
//remove any leftovers to make sure it's precise
liquids.remove(consumeLiquid, consumeLiquidAmount - liquidRemoved);
landEffect.at(this);
Effect.shake(3f, 3f, this);
items.set(arriving, itemCapacity);
state.getSector().info.handleItemImport(arriving, itemCapacity);
arriving = null;
arrivingTimer = 0f;
}
}
if(items.total() > 0){
dumpAccumulate(config == null || items.get(config) != items.total() ? null : config);
}
if(arriving == null){
cooldown -= delta() / cooldownTime;
cooldown = Mathf.clamp(cooldown);
}
if(config != null && state.isCampaign()){
cooldown -= delta() / cooldownTime;
if(cooldown <= 0f && efficiency > 0f && items.total() == 0 && state.rules.sector.info.importCooldownTimers.get(config, 0f) >= 1f){
if(cooldown <= 0f && efficiency > 0f && items.total() == 0 && state.rules.sector.info.getImportRate(state.getPlanet(), config) > 0f && state.rules.sector.info.importCooldownTimers.get(config, 0f) >= 1f){
//queue landing for next frame
waiting.get(config, Seq::new).add(this);
@ -184,6 +312,58 @@ public class LandingPad extends Block{
@Override
public void buildConfiguration(Table table){
ItemSelection.buildTable(LandingPad.this, table, content.items(), () -> config, this::configure, selectionRows, selectionColumns);
if(!net.client()){
table.row();
table.table(t -> {
t.background(Styles.black6);
t.button(Icon.downOpen, Styles.clearNonei, 40f, () -> {
if(config != null && state.isCampaign()){
for(Sector sector : state.getPlanet().sectors){
if(sector.hasBase() && sector != state.getSector() && sector.info.destination != state.getSector() && sector.info.hasExport(config)){
sector.info.destination = state.getSector();
sector.saveInfo();
}
}
state.getSector().info.refreshImportRates(state.getPlanet());
}
}).disabled(b -> config == null || !state.isCampaign() || (!state.getPlanet().sectors.contains(s -> s.hasBase() && s.info.hasExport(config) && s.info.destination != state.getSector())))
.tooltip("@sectors.redirect").get();
}).fillX().left();
}
}
@Override
public void display(Table table){
super.display(table);
if(!state.isCampaign() || net.client() || team != player.team()) return;
table.row();
table.label(() -> {
if(config == null || !state.isCampaign()){
return "";
}
int sources = 0;
float perSecond = 0f;
for(var s : state.getPlanet().sectors){
if(s != state.getSector() && s.hasBase() && s.info.destination == state.getSector()){
float amount = s.info.getExport(config);
if(amount > 0){
sources ++;
perSecond += s.info.getExport(config);
}
}
}
String str = Core.bundle.format("landing.sources", sources == 0 ? Core.bundle.get("none") : sources);
if(perSecond > 0){
str += "\n" + Core.bundle.format("landing.import", config.emoji(), (int)(perSecond * 60f));
}
return str;
}).pad(4).wrap().width(200f).left();
}
@Override

View file

@ -22,6 +22,7 @@ import mindustry.logic.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.liquid.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*;
@ -36,6 +37,13 @@ public class LaunchPad extends Block{
public Color lightColor = Color.valueOf("eab678");
public boolean acceptMultipleItems = false;
public float lightStep = 1f;
public int lightSteps = 3;
public float liquidPad = 2f;
public @Nullable Liquid drawLiquid;
public Color bottomColor = Pal.darkerMetal;
public LaunchPad(String name){
super(name);
hasItems = true;
@ -87,6 +95,13 @@ public class LaunchPad extends Block{
@Override
public void draw(){
if(hasLiquids && drawLiquid != null){
Draw.color(bottomColor);
Fill.square(x, y, size * tilesize/2f - liquidPad);
Draw.color();
LiquidBlock.drawTiledFrames(block.size, x, y, liquidPad, liquidPad, liquidPad, liquidPad, drawLiquid, liquids.get(drawLiquid) / liquidCapacity);
}
super.draw();
if(!state.isCampaign()) return;
@ -94,13 +109,11 @@ public class LaunchPad extends Block{
if(lightRegion.found()){
Draw.color(lightColor);
float progress = Math.min((float)items.total() / itemCapacity, launchCounter / launchTime);
int steps = 3;
float step = 1f;
for(int i = 0; i < 4; i++){
for(int j = 0; j < steps; j++){
float alpha = Mathf.curve(progress, (float)j / steps, (j+1f) / steps);
float offset = -(j - 1f) * step;
for(int j = 0; j < lightSteps; j++){
float alpha = Mathf.curve(progress, (float)j / lightSteps, (j+1f) / lightSteps);
float offset = -(j - 1f) * lightStep;
Draw.color(Pal.metalGrayDark, lightColor, alpha);
Draw.rect(lightRegion, x + Geometry.d8edge(i).x * offset, y + Geometry.d8edge(i).y * offset, i * 90);
@ -110,6 +123,7 @@ public class LaunchPad extends Block{
Draw.reset();
}
Drawf.shadow(x, y, size * tilesize);
Draw.rect(podRegion, x, y);
Draw.reset();
@ -169,7 +183,11 @@ public class LaunchPad extends Block{
table.button(Icon.upOpen, Styles.cleari, () -> {
ui.planet.showSelect(state.rules.sector, other -> {
if(state.isCampaign() && other.planet == state.rules.sector.planet){
var prev = state.rules.sector.info.destination;
state.rules.sector.info.destination = other;
if(prev != null){
prev.info.refreshImportRates(state.getPlanet());
}
}
});
deselect();

View file

@ -150,7 +150,7 @@ public class StatValues{
t.add(Strings.autoFixed(amount, 2)).style(Styles.outlineLabel);
add(t);
}
}}).size(iconMed).padRight(3 + (amount != 0 && Strings.autoFixed(amount, 2).length() > 2 ? 8 : 0)).with(s -> withTooltip(s, liquid, false));
}}).size(iconMed).padRight(3 + (amount != 0 ? (Strings.autoFixed(amount, 2).length() - 1) * 10 : 0)).with(s -> withTooltip(s, liquid, false));
if(perSecond && amount != 0){
t.add(StatUnit.perSecond.localized()).padLeft(2).padRight(5).color(Color.lightGray).style(Styles.outlineLabel);

View file

@ -26,4 +26,4 @@ org.gradle.caching=true
org.gradle.internal.http.socketTimeout=100000
org.gradle.internal.http.connectionTimeout=100000
android.enableR8.fullMode=false
archash=99a42db331
archash=c8004178c4

View file

@ -15,10 +15,6 @@ if(new File(settingsDir, 'local.properties').exists()){
if(System.getenv("JITPACK") == "true") hasSdk = false
if(hasSdk){
//hack: pretend the Android module doesn't exist when imported through IntelliJ
//why? because IntelliJ chokes on the new version of the Android plugin
//UPDATE: it no longer chokes on AGP with the latest version, but instead gives a completely different error. brilliant.
include 'android'
}else{
println("No Android SDK found. Skipping Android module.")