Configurable plans, taken from Foo's

This commit is contained in:
Anuken
2024-10-28 16:54:01 -04:00
parent fd88550b88
commit bbff564f96
10 changed files with 152 additions and 4 deletions

View File

@@ -548,6 +548,7 @@ public class Renderer implements ApplicationListener{
public void showLaunch(CoreBuild landCore, CoreBlock coreType){
control.input.config.hideConfig();
control.input.planConfig.hide();
control.input.inv.hide();
this.landCore = landCore;

View File

@@ -4,6 +4,7 @@ import arc.func.*;
import arc.math.geom.*;
import arc.math.geom.QuadTree.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.*;
@@ -64,7 +65,6 @@ public class BuildPlan implements Position, QuadTreeObject{
public BuildPlan(){
}
public boolean placeable(Team team){
return Build.validPlace(block, team, x, y, rotation);
}
@@ -152,6 +152,17 @@ public class BuildPlan implements Position, QuadTreeObject{
return y*tilesize + (block == null ? 0 : block.offset);
}
public boolean isDone(){
Tile tile = world.tile(x, y);
if(tile == null) return true;
Block tblock = tile.block();
if(breaking){
return tblock == Blocks.air || tblock == tile.floor();
}else{
return tblock == block && (tile.build == null || tile.build.rotation == rotation);
}
}
public @Nullable Tile tile(){
return world.tile(x, y);
}

View File

@@ -783,6 +783,15 @@ public class DesktopInput extends InputHandler{
if(getPlan(splan.x, splan.y, splan.block.size, splan) != null){
player.unit().plans().remove(splan, true);
}
if(input.ctrl()){
inv.hide();
config.hideConfig();
planConfig.showConfig(splan);
}else{
planConfig.hide();
}
splan = null;
}

View File

@@ -116,6 +116,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public final BlockInventoryFragment inv;
public final BlockConfigFragment config;
public final PlanConfigFragment planConfig;
private WidgetGroup group = new WidgetGroup();
@@ -136,6 +137,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
group.touchable = Touchable.childrenOnly;
inv = new BlockInventoryFragment();
config = new BlockConfigFragment();
planConfig = new PlanConfigFragment();
Events.on(UnitDestroyEvent.class, e -> {
if(e.unit != null && e.unit.isPlayer() && e.unit.getPlayer().isLocal() && e.unit.type.weapons.contains(w -> w.bullet.killShooter)){
@@ -1622,6 +1624,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
/** Handles tile tap events that are not platform specific. */
boolean tileTapped(@Nullable Building build){
planConfig.hide();
if(build == null){
inv.hide();
config.hideConfig();
@@ -1897,6 +1900,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
inv.build(group);
config.build(group);
planConfig.build(group);
}
}

View File

@@ -0,0 +1,83 @@
package mindustry.ui.fragments;
import arc.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.*;
import arc.scene.actions.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.ctype.*;
import mindustry.entities.units.*;
import mindustry.game.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import static mindustry.Vars.*;
/**
* Displays the configuration UI for build plans before they have been placed.
* Shamelessly stolen from Foo's Client.
*/
public class PlanConfigFragment{
Table table = new Table();
BuildPlan selected;
public void build(Group parent){
table.visible = false;
parent.addChild(table);
Events.on(EventType.ResetEvent.class, e -> forceHide());
}
public void showConfig(BuildPlan plan){
if(this.selected == plan || plan.block == null){
hide();
return;
}
Block block = plan.block;
if(!block.configurable) return;
selected = plan;
table.clear();
var options = new Seq<UnlockableContent>();
block.getPlanConfigs(options);
if(options.isEmpty()) return;
ItemSelection.buildTable(
table, options,
() -> selected != null ? (selected.config instanceof UnlockableContent c ? c : null) : null,
content -> {
selected.config = content;
hide();
},
block.selectionRows, block.selectionColumns
);
table.pack();
table.setTransform(true);
table.visible = true;
table.actions(Actions.scaleTo(0f, 1f), Actions.visible(true),
Actions.scaleTo(1f, 1f, 0.07f, Interp.pow3Out));
table.update(() -> {
table.setOrigin(Align.center);
if(plan.isDone() || !(control.input.selectPlans.contains(plan) || player.unit().plans.contains(plan))){
this.hide();
return;
}
Vec2 pos = Core.input.mouseScreen(plan.drawx(), plan.drawy() - block.size * tilesize / 2.0F - 1);
table.setPosition(pos.x, pos.y, Align.top);
});
}
public void forceHide(){
table.visible = false;
selected = null;
}
public void hide(){
selected = null;
table.actions(Actions.scaleTo(0f, 1f, 0.06f, Interp.pow3Out), Actions.visible(false));
}
}

View File

@@ -1431,6 +1431,16 @@ public class Block extends UnlockableContent implements Senseable{
}
}
/** Fills the specified array with the list of configuration options this block has. Only used for plans. */
public void getPlanConfigs(Seq<UnlockableContent> options){
if(configurations.containsKey(Item.class)){
options.add(content.items());
}
if(configurations.containsKey(Liquid.class)){
options.add(content.liquids());
}
}
@Override
public double sense(LAccess sensor){
return switch(sensor){

View File

@@ -7,6 +7,7 @@ import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.*;
import mindustry.ctype.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.blocks.storage.*;
@@ -44,10 +45,15 @@ public class Constructor extends BlockProducer{
stats.add(Stat.output, "@x@ ~ @x@", minBlockSize, minBlockSize, maxBlockSize, maxBlockSize);
}
@Override
public void getPlanConfigs(Seq<UnlockableContent> options){
options.add(content.blocks().select(this::canProduce));
}
public boolean canProduce(Block b){
return b.isVisible() && b.size >= minBlockSize && b.size <= maxBlockSize && !(b instanceof CoreBlock) && !state.rules.isBanned(b) && b.environmentBuildable() && (filter.isEmpty() || filter.contains(b));
}
public class ConstructorBuild extends BlockProducerBuild{
public @Nullable Block recipe;
@@ -65,7 +71,7 @@ public class Constructor extends BlockProducer{
public Object config(){
return recipe;
}
@Override
public void drawSelect(){
if(recipe != null){

View File

@@ -4,6 +4,7 @@ import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.*;
@@ -22,7 +23,7 @@ import static mindustry.Vars.*;
public class PayloadRouter extends PayloadConveyor{
public boolean invert = false;
public @Load("@-over") TextureRegion overRegion;
public PayloadRouter(String name){
@@ -45,6 +46,12 @@ public class PayloadRouter extends PayloadConveyor{
Draw.rect(overRegion, plan.drawx(), plan.drawy());
}
@Override
public void getPlanConfigs(Seq<UnlockableContent> options){
options.add(content.blocks().select(this::canSort));
options.add(content.units().select(this::canSort));
}
public boolean canSort(Block b){
return b.isVisible() && b.size <= size && !(b instanceof CoreBlock) && !state.rules.isBanned(b) && b.environmentBuildable();
}

View File

@@ -5,6 +5,7 @@ import arc.graphics.g2d.*;
import arc.math.*;
import arc.math.geom.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.*;
@@ -66,6 +67,12 @@ public class PayloadSource extends PayloadBlock{
});
}
@Override
public void getPlanConfigs(Seq<UnlockableContent> options){
options.add(content.blocks().select(this::canProduce));
options.add(content.units().select(this::canProduce));
}
@Override
public TextureRegion[] icons(){
return new TextureRegion[]{region, outRegion, topRegion};

View File

@@ -13,6 +13,7 @@ import arc.util.*;
import arc.util.io.*;
import mindustry.*;
import mindustry.ai.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
@@ -172,6 +173,15 @@ public class UnitFactory extends UnitBlock{
Draw.rect(topRegion, plan.drawx(), plan.drawy());
}
@Override
public void getPlanConfigs(Seq<UnlockableContent> options){
for(var plan : plans){
if(!plan.unit.isBanned()){
options.add(plan.unit);
}
}
}
public static class UnitPlan{
public UnitType unit;
public ItemStack[] requirements;