From b854b0ca227b0ed5d6905a78f839795cbd2547d6 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 1 Sep 2022 17:49:29 -0400 Subject: [PATCH 1/2] Better item selection UI --- .../mindustry/ctype/UnlockableContent.java | 2 + core/src/mindustry/type/UnitType.java | 1 + core/src/mindustry/world/Block.java | 3 + .../mindustry/world/blocks/ItemSelection.java | 87 +++++++++++++------ .../world/blocks/distribution/Sorter.java | 4 +- .../world/blocks/payloads/Constructor.java | 4 +- .../world/blocks/payloads/PayloadSource.java | 3 +- .../world/blocks/sandbox/ItemSource.java | 4 +- .../world/blocks/sandbox/LiquidSource.java | 4 +- .../world/blocks/storage/Unloader.java | 4 +- .../world/blocks/units/UnitFactory.java | 4 +- 11 files changed, 79 insertions(+), 41 deletions(-) diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index 4471f7552c..566b625205 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -36,6 +36,8 @@ public abstract class UnlockableContent extends MappableContent{ public boolean generateIcons = true; /** Special logic icon ID. */ public int iconId = 0; + /** How big the content appears in certain selection menus */ + public float selectionSize = 24f; /** Icon of the content to use in UI. */ public TextureRegion uiIcon; /** Icon of the full content. Unscaled.*/ diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 3ffa005310..458b8f32d0 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -423,6 +423,7 @@ public class UnitType extends UnlockableContent{ super(name); constructor = EntityMapping.map(this.name); + selectionSize = 30f; } public UnitController createController(Unit unit){ diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index dd338b4f5e..c64718d56b 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -211,6 +211,8 @@ public class Block extends UnlockableContent implements Senseable{ public boolean commandable; /** If true, the building inventory can be shown with the config. */ public boolean allowConfigInventory = true; + /** Defines how large selection menus, such as that of sorters, should be. */ + public int selectionRows = 5, selectionColumns = 4; /** If true, this block can be configured by logic. */ public boolean logicConfigurable = false; /** Whether this block consumes touchDown events when tapped. */ @@ -365,6 +367,7 @@ public class Block extends UnlockableContent implements Senseable{ public Block(String name){ super(name); initBuilding(); + selectionSize = 28f; } public void drawBase(Tile tile){ diff --git a/core/src/mindustry/world/blocks/ItemSelection.java b/core/src/mindustry/world/blocks/ItemSelection.java index c444f2a4ac..1f833e6958 100644 --- a/core/src/mindustry/world/blocks/ItemSelection.java +++ b/core/src/mindustry/world/blocks/ItemSelection.java @@ -1,6 +1,7 @@ package mindustry.world.blocks; import arc.func.*; +import arc.math.*; import arc.scene.style.*; import arc.scene.ui.*; import arc.scene.ui.layout.*; @@ -15,49 +16,78 @@ import mindustry.world.*; import static mindustry.Vars.*; public class ItemSelection{ + private static TextField search; + private static int rowCount; public static void buildTable(Table table, Seq items, Prov holder, Cons consumer){ buildTable(table, items, holder, consumer, true); } - public static void buildTable(Block block, Table table, Seq items, Prov holder, Cons consumer){ - buildTable(block, table, items, holder, consumer, true); - } - public static void buildTable(Table table, Seq items, Prov holder, Cons consumer, boolean closeSelect){ - buildTable(null, table, items, holder, consumer, closeSelect); + buildTable(null, table, items, holder, consumer, closeSelect, 5, 4); } - - public static void buildTable(@Nullable Block block, Table table, Seq items, Prov holder, Cons consumer, boolean closeSelect){ + public static void buildTable(Table table, Seq items, Prov holder, Cons consumer, int columns){ + buildTable(null, table, items, holder, consumer, true, 5, columns); + } + + public static void buildTable(Block block, Table table, Seq items, Prov holder, Cons consumer){ + buildTable(block, table, items, holder, consumer, true, 5, 4); + } + + public static void buildTable(Block block, Table table, Seq items, Prov holder, Cons consumer, boolean closeSelect){ + buildTable(block, table, items, holder, consumer, closeSelect, 5 ,4); + } + + public static void buildTable(Block block, Table table, Seq items, Prov holder, Cons consumer, int rows, int columns){ + buildTable(block, table, items, holder, consumer, true, rows, columns); + } + + public static void buildTable(Table table, Seq items, Prov holder, Cons consumer, int rows, int columns){ + buildTable(null, table, items, holder, consumer, true, rows, columns); + } + + public static void buildTable(@Nullable Block block, Table table, Seq items, Prov holder, Cons consumer, boolean closeSelect, int rows, int columns){ ButtonGroup group = new ButtonGroup<>(); group.setMinCheckCount(0); - Table cont = new Table(); + Table cont = new Table().top(); cont.defaults().size(40); - int i = 0; + if(search != null) search.clearText(); - for(T item : items){ - if(!item.unlockedNow() || (item instanceof Item checkVisible && state.rules.hiddenBuildItems.contains(checkVisible)) || item.isHidden()) continue; + Runnable rebuild = () -> { + group.clear(); + cont.clearChildren(); - ImageButton button = cont.button(Tex.whiteui, Styles.clearTogglei, 24, () -> { - if(closeSelect) control.input.config.hideConfig(); - }).group(group).tooltip(item.localizedName).get(); - button.changed(() -> consumer.get(button.isChecked() ? item : null)); - button.getStyle().imageUp = new TextureRegionDrawable(item.uiIcon); - button.update(() -> button.setChecked(holder.get() == item)); + var text = search != null ? search.getText() : ""; + int i = 0; + rowCount = 0; - if(i++ % 4 == 3){ - cont.row(); + Seq list = items.select(u -> (text.isEmpty() || u.localizedName.toLowerCase().contains(text.toLowerCase()))); + for(T item : list){ + if(!item.unlockedNow() || (item instanceof Item checkVisible && state.rules.hiddenBuildItems.contains(checkVisible)) || item.isHidden()) continue; + + ImageButton button = cont.button(Tex.whiteui, Styles.clearNoneTogglei, Mathf.clamp(item.selectionSize, 0f, 40f), () -> { + if(closeSelect) control.input.config.hideConfig(); + }).tooltip(item.localizedName).group(group).get(); + button.changed(() -> consumer.get(button.isChecked() ? item : null)); + button.getStyle().imageUp = new TextureRegionDrawable(item.uiIcon); + button.update(() -> button.setChecked(holder.get() == item)); + + if(i++ % columns == (columns - 1)){ + cont.row(); + rowCount++; + } } - } + }; - //add extra blank spaces so it looks nice - if(i % 4 != 0){ - int remaining = 4 - (i % 4); - for(int j = 0; j < remaining; j++){ - cont.image(Styles.black6); - } + rebuild.run(); + + Table main = new Table().background(Styles.black6); + if(rowCount > rows * 1.5f){ + search = main.field(null, text -> rebuild.run()).width(40 * columns).padBottom(4).left().growX().get(); + search.setMessageText("@players.search"); + main.row(); } ScrollPane pane = new ScrollPane(cont, Styles.smallPane); @@ -71,6 +101,7 @@ public class ItemSelection{ } pane.setOverscroll(false, false); - table.add(pane).maxHeight(Scl.scl(40 * 5)); + main.add(pane).maxHeight(40 * rows); + table.top().add(main); } -} +} \ No newline at end of file diff --git a/core/src/mindustry/world/blocks/distribution/Sorter.java b/core/src/mindustry/world/blocks/distribution/Sorter.java index 5e19c65966..b37195173c 100644 --- a/core/src/mindustry/world/blocks/distribution/Sorter.java +++ b/core/src/mindustry/world/blocks/distribution/Sorter.java @@ -126,7 +126,7 @@ public class Sorter extends Block{ @Override public void buildConfiguration(Table table){ - ItemSelection.buildTable(Sorter.this, table, content.items(), () -> sortItem, this::configure); + ItemSelection.buildTable(Sorter.this, table, content.items(), () -> sortItem, this::configure, selectionRows, selectionColumns); } @Override @@ -155,4 +155,4 @@ public class Sorter extends Block{ } } } -} +} \ No newline at end of file diff --git a/core/src/mindustry/world/blocks/payloads/Constructor.java b/core/src/mindustry/world/blocks/payloads/Constructor.java index f27197e72e..bc13018691 100644 --- a/core/src/mindustry/world/blocks/payloads/Constructor.java +++ b/core/src/mindustry/world/blocks/payloads/Constructor.java @@ -58,7 +58,7 @@ public class Constructor extends BlockProducer{ @Override public void buildConfiguration(Table table){ - ItemSelection.buildTable(Constructor.this, table, filter.isEmpty() ? content.blocks().select(Constructor.this::canProduce) : filter, () -> recipe, this::configure); + ItemSelection.buildTable(Constructor.this, table, filter.isEmpty() ? content.blocks().select(Constructor.this::canProduce) : filter, () -> recipe, this::configure, selectionRows, selectionColumns); } @Override @@ -91,4 +91,4 @@ public class Constructor extends BlockProducer{ recipe = Vars.content.block(read.s()); } } -} +} \ No newline at end of file diff --git a/core/src/mindustry/world/blocks/payloads/PayloadSource.java b/core/src/mindustry/world/blocks/payloads/PayloadSource.java index 9a2012fc5e..b6f6de2380 100644 --- a/core/src/mindustry/world/blocks/payloads/PayloadSource.java +++ b/core/src/mindustry/world/blocks/payloads/PayloadSource.java @@ -29,6 +29,7 @@ public class PayloadSource extends PayloadBlock{ hasPower = false; rotate = true; configurable = true; + selectionRows = selectionColumns = 8; //make sure to display large units. clipSize = 120; noUpdateDisabled = true; @@ -103,7 +104,7 @@ public class PayloadSource extends PayloadBlock{ ItemSelection.buildTable(PayloadSource.this, table, content.blocks().select(PayloadSource.this::canProduce).as() .add(content.units().select(PayloadSource.this::canProduce).as()), - () -> (UnlockableContent)config(), this::configure); + () -> (UnlockableContent)config(), this::configure, selectionRows, selectionColumns); } @Override diff --git a/core/src/mindustry/world/blocks/sandbox/ItemSource.java b/core/src/mindustry/world/blocks/sandbox/ItemSource.java index c0d1aef175..06afbd3e66 100644 --- a/core/src/mindustry/world/blocks/sandbox/ItemSource.java +++ b/core/src/mindustry/world/blocks/sandbox/ItemSource.java @@ -89,7 +89,7 @@ public class ItemSource extends Block{ @Override public void buildConfiguration(Table table){ - ItemSelection.buildTable(ItemSource.this, table, content.items(), () -> outputItem, this::configure); + ItemSelection.buildTable(ItemSource.this, table, content.items(), () -> outputItem, this::configure, selectionRows, selectionColumns); } @Override @@ -114,4 +114,4 @@ public class ItemSource extends Block{ outputItem = content.item(read.s()); } } -} +} \ No newline at end of file diff --git a/core/src/mindustry/world/blocks/sandbox/LiquidSource.java b/core/src/mindustry/world/blocks/sandbox/LiquidSource.java index be5cf94619..56def6fd71 100644 --- a/core/src/mindustry/world/blocks/sandbox/LiquidSource.java +++ b/core/src/mindustry/world/blocks/sandbox/LiquidSource.java @@ -85,7 +85,7 @@ public class LiquidSource extends Block{ @Override public void buildConfiguration(Table table){ - ItemSelection.buildTable(LiquidSource.this, table, content.liquids(), () -> source, this::configure); + ItemSelection.buildTable(LiquidSource.this, table, content.liquids(), () -> source, this::configure, selectionRows, selectionColumns); } @Override @@ -111,4 +111,4 @@ public class LiquidSource extends Block{ source = id == -1 ? null : content.liquid(id); } } -} +} \ No newline at end of file diff --git a/core/src/mindustry/world/blocks/storage/Unloader.java b/core/src/mindustry/world/blocks/storage/Unloader.java index 2a4553b2ed..85b0ed8667 100644 --- a/core/src/mindustry/world/blocks/storage/Unloader.java +++ b/core/src/mindustry/world/blocks/storage/Unloader.java @@ -224,7 +224,7 @@ public class Unloader extends Block{ @Override public void buildConfiguration(Table table){ - ItemSelection.buildTable(Unloader.this, table, content.items(), () -> sortItem, this::configure); + ItemSelection.buildTable(Unloader.this, table, content.items(), () -> sortItem, this::configure, selectionRows, selectionColumns); } @Override @@ -250,4 +250,4 @@ public class Unloader extends Block{ sortItem = id == -1 ? null : content.item(id); } } -} +} \ No newline at end of file diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 755633b8b6..bfbda241c5 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -211,7 +211,7 @@ public class UnitFactory extends UnitBlock{ Seq units = Seq.with(plans).map(u -> u.unit).filter(u -> u.unlockedNow() && !u.isBanned()); if(units.any()){ - ItemSelection.buildTable(UnitFactory.this, table, units, () -> currentPlan == -1 ? null : plans.get(currentPlan).unit, unit -> configure(plans.indexOf(u -> u.unit == unit))); + ItemSelection.buildTable(UnitFactory.this, table, units, () -> currentPlan == -1 ? null : plans.get(currentPlan).unit, unit -> configure(plans.indexOf(u -> u.unit == unit)), selectionRows, selectionColumns); }else{ table.table(Styles.black3, t -> t.add("@none").color(Color.lightGray)); } @@ -357,4 +357,4 @@ public class UnitFactory extends UnitBlock{ } } } -} +} \ No newline at end of file From e9d3adfef3abc4ef025a99c1afc83a04e65bfa6f Mon Sep 17 00:00:00 2001 From: MEEPofFaith <54301439+MEEPofFaith@users.noreply.github.com> Date: Thu, 1 Sep 2022 17:47:53 -0700 Subject: [PATCH 2/2] Options for `SectorPreset` overriding plant launch fields. (#7478) * Preset overriding loadouts * a * You know I should really learn what this actually does --- core/src/mindustry/type/Sector.java | 8 ++++++++ core/src/mindustry/type/SectorPreset.java | 6 ++++++ core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java | 10 +++++----- core/src/mindustry/ui/dialogs/PlanetDialog.java | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/core/src/mindustry/type/Sector.java b/core/src/mindustry/type/Sector.java index e4d6658ab5..b4bb3006ac 100644 --- a/core/src/mindustry/type/Sector.java +++ b/core/src/mindustry/type/Sector.java @@ -80,6 +80,14 @@ public class Sector{ return hasBase() || (preset != null && preset.alwaysUnlocked); } + public boolean allowLaunchSchematics(){ + return (preset != null && preset.overrideLaunchDefaults) ? preset.allowLaunchSchematics : planet.allowLaunchSchematics; + } + + public boolean allowLaunchLoadout(){ + return (preset != null && preset.overrideLaunchDefaults) ? preset.allowLaunchLoadout : planet.allowLaunchLoadout; + } + public void saveInfo(){ Core.settings.putJson(planet.name + "-s-" + id + "-info", info); } diff --git a/core/src/mindustry/type/SectorPreset.java b/core/src/mindustry/type/SectorPreset.java index eebbb16b9d..823e388c1a 100644 --- a/core/src/mindustry/type/SectorPreset.java +++ b/core/src/mindustry/type/SectorPreset.java @@ -18,6 +18,12 @@ public class SectorPreset extends UnlockableContent{ public float startWaveTimeMultiplier = 2f; public boolean addStartingItems = false; public boolean showSectorLandInfo = true; + /** If true, uses this sector's launch fields instead */ + public boolean overrideLaunchDefaults = false; + /** Whether to allow users to specify a custom launch schematic for this map. */ + public boolean allowLaunchSchematics = false; + /** Whether to allow users to specify the resources they take to this map. */ + public boolean allowLaunchLoadout = false; /** If true, switches to attack mode after waves end. */ public boolean attackAfterWaves = false; diff --git a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java index dd1bcd3c64..abd86f80a6 100644 --- a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java +++ b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java @@ -55,7 +55,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ int capacity = lastCapacity; - if(!sector.planet.allowLaunchLoadout){ + if(!destination.allowLaunchLoadout()){ resources.clear(); //TODO this should be set to a proper loadout based on sector. if(destination.preset != null){ @@ -95,7 +95,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ table.image(s.item.uiIcon).left().size(iconSmall); - String amountStr = (al + as) + (sector.planet.allowLaunchLoadout ? "[gray] (" + (al + " + " + as + ")") : ""); + String amountStr = (al + as) + (destination.allowLaunchLoadout() ? "[gray] (" + (al + " + " + as + ")") : ""); table.add( sitems.has(s.item, s.amount) ? amountStr : @@ -111,7 +111,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ Runnable rebuildItems = () -> rebuild.get(items); - if(sector.planet.allowLaunchLoadout){ + if(destination.allowLaunchLoadout()){ buttons.button("@resources.max", Icon.add, Styles.togglet, () -> { setMax(!getMax()); update.run(); @@ -154,7 +154,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ cont.add(Core.bundle.format("launch.from", sector.name())).row(); - if(sector.planet.allowLaunchSchematics){ + if(destination.allowLaunchSchematics()){ cont.pane(t -> { int[] i = {0}; @@ -176,7 +176,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ } }; - if(sector.planet.allowLaunchSchematics || schematics.getDefaultLoadout(core) == null){ + if(destination.allowLaunchSchematics() || schematics.getDefaultLoadout(core) == null){ for(var entry : schematics.getLoadouts()){ if(entry.key.size <= core.size){ for(Schematic s : entry.value){ diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index 8835f123aa..414a7a5046 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -1160,7 +1160,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ //free launch. control.playSector(sector); }else{ - CoreBlock block = from.planet.allowLaunchSchematics ? (from.info.bestCoreType instanceof CoreBlock b ? b : (CoreBlock)from.planet.defaultCore) : (CoreBlock)from.planet.defaultCore; + CoreBlock block = sector.allowLaunchSchematics() ? (from.info.bestCoreType instanceof CoreBlock b ? b : (CoreBlock)from.planet.defaultCore) : (CoreBlock)from.planet.defaultCore; loadouts.show(block, from, sector, () -> { var schemCore = universe.getLastLoadout().findCore();