From d34631458e32cb8cbe6b6aa9dde00cc5da812806 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 11 May 2023 13:41:45 -0400 Subject: [PATCH] Mobile rebuild button support --- core/assets/bundles/bundle.properties | 2 + core/src/mindustry/input/DesktopInput.java | 33 +------- core/src/mindustry/input/InputHandler.java | 29 +++++++ core/src/mindustry/input/MobileInput.java | 81 ++++++++++++------- core/src/mindustry/ui/dialogs/JoinDialog.java | 4 +- .../mindustry/ui/dialogs/PlanetDialog.java | 2 +- .../mindustry/ui/fragments/HintsFragment.java | 2 +- 7 files changed, 90 insertions(+), 63 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 8b0088943c..44c94fb788 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1789,6 +1789,8 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \uE827 [accent]Map[] in the \uE88C [accent]Menu[]. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. +hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically. + hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \uE844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index f24d4cba74..70277ef24e 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -12,20 +12,15 @@ import arc.scene.*; import arc.scene.ui.layout.*; import arc.util.*; import mindustry.*; -import mindustry.content.*; import mindustry.core.*; import mindustry.entities.units.*; import mindustry.game.EventType.*; import mindustry.game.*; -import mindustry.game.Teams.*; import mindustry.gen.*; import mindustry.graphics.*; -import mindustry.input.Placement.*; import mindustry.ui.*; import mindustry.world.*; -import java.util.*; - import static arc.Core.*; import static mindustry.Vars.*; import static mindustry.input.PlaceMode.*; @@ -119,19 +114,7 @@ public class DesktopInput extends InputHandler{ if(Core.input.keyDown(Binding.schematic_select)){ drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize); }else if(Core.input.keyDown(Binding.rebuild_select)){ - //TODO color? - drawSelection(schemX, schemY, cursorX, cursorY, 0, Pal.sapBulletBack, Pal.sapBullet); - - NormalizeDrawResult result = Placement.normalizeDrawArea(Blocks.air, schemX, schemY, cursorX, cursorY, false, 0, 1f); - - Tmp.r1.set(result.x, result.y, result.x2 - result.x, result.y2 - result.y); - - for(BlockPlan plan : player.team().data().plans){ - Block block = content.block(plan.block); - if(block.bounds(plan.x, plan.y, Tmp.r2).overlaps(Tmp.r1)){ - drawSelected(plan.x, plan.y, content.block(plan.block), Pal.sapBullet); - } - } + drawRebuildSelection(schemX, schemY, cursorX, cursorY); } } @@ -529,20 +512,8 @@ public class DesktopInput extends InputHandler{ schemX = -1; schemY = -1; }else if(input.keyRelease(Binding.rebuild_select)){ - //TODO rebuild!!! - - NormalizeResult result = Placement.normalizeArea(schemX, schemY, rawCursorX, rawCursorY, rotation, false, 999999999); - Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize); - - Iterator broken = player.team().data().plans.iterator(); - while(broken.hasNext()){ - BlockPlan plan = broken.next(); - Block block = content.block(plan.block); - if(block.bounds(plan.x, plan.y, Tmp.r2).overlaps(Tmp.r1)){ - player.unit().addBuild(new BuildPlan(plan.x, plan.y, plan.rotation, content.block(plan.block), plan.config)); - } - } + rebuildArea(schemX, schemY, rawCursorX, rawCursorY); schemX = -1; schemY = -1; } diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 9a456b1fd0..2c95874dc9 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -1166,6 +1166,21 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y); } + protected void drawRebuildSelection(int x, int y, int x2, int y2){ + drawSelection(x, y, x2, y2, 0, Pal.sapBulletBack, Pal.sapBullet); + + NormalizeDrawResult result = Placement.normalizeDrawArea(Blocks.air, x, y, x2, y2, false, 0, 1f); + + Tmp.r1.set(result.x, result.y, result.x2 - result.x, result.y2 - result.y); + + for(BlockPlan plan : player.team().data().plans){ + Block block = content.block(plan.block); + if(block.bounds(plan.x, plan.y, Tmp.r2).overlaps(Tmp.r1)){ + drawSelected(plan.x, plan.y, content.block(plan.block), Pal.sapBullet); + } + } + } + protected void drawBreakSelection(int x1, int y1, int x2, int y2){ drawBreakSelection(x1, y1, x2, y2, maxLength); } @@ -1653,6 +1668,20 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } } + public void rebuildArea(int x, int y, int x2, int y2){ + NormalizeResult result = Placement.normalizeArea(x, y, x2, y2, rotation, false, 999999999); + Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize); + + Iterator broken = player.team().data().plans.iterator(); + while(broken.hasNext()){ + BlockPlan plan = broken.next(); + Block block = content.block(plan.block); + if(block.bounds(plan.x, plan.y, Tmp.r2).overlaps(Tmp.r1)){ + player.unit().addBuild(new BuildPlan(plan.x, plan.y, plan.rotation, content.block(plan.block), plan.config)); + } + } + } + public void tryBreakBlock(int x, int y){ if(validBreak(x, y)){ breakBlock(x, y); diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index f9d183cafd..b70d09228f 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -55,7 +55,7 @@ public class MobileInput extends InputHandler implements GestureListener{ /** Whether the player is currently shifting all placed tiles. */ public boolean selecting; /** Whether the player is currently in line-place mode. */ - public boolean lineMode, schematicMode; + public boolean lineMode, schematicMode, rebuildMode; /** Current place mode. */ public PlaceMode mode = none; /** Whether no recipe was available when switching to break mode. */ @@ -208,6 +208,8 @@ public class MobileInput extends InputHandler implements GestureListener{ if(schematicMode){ block = null; mode = none; + }else{ + rebuildMode = false; } } }).update(i -> { @@ -219,37 +221,45 @@ public class MobileInput extends InputHandler implements GestureListener{ }); //confirm button - table.button(Icon.ok, Styles.clearNonei, () -> { - for(BuildPlan plan : selectPlans){ - Tile tile = plan.tile(); + table.button(Icon.ok, Styles.clearNoneTogglei, () -> { + if(schematicMode){ + rebuildMode = !rebuildMode; + }else{ + for(BuildPlan plan : selectPlans){ + Tile tile = plan.tile(); - //actually place/break all selected blocks - if(tile != null){ - if(!plan.breaking){ - if(validPlace(plan.x, plan.y, plan.block, plan.rotation)){ - BuildPlan other = getPlan(plan.x, plan.y, plan.block.size, null); - BuildPlan copy = plan.copy(); + //actually place/break all selected blocks + if(tile != null){ + if(!plan.breaking){ + if(validPlace(plan.x, plan.y, plan.block, plan.rotation)){ + BuildPlan other = getPlan(plan.x, plan.y, plan.block.size, null); + BuildPlan copy = plan.copy(); - if(other == null){ - player.unit().addBuild(copy); - }else if(!other.breaking && other.x == plan.x && other.y == plan.y && other.block.size == plan.block.size){ - player.unit().plans().remove(other); - player.unit().addBuild(copy); + if(other == null){ + player.unit().addBuild(copy); + }else if(!other.breaking && other.x == plan.x && other.y == plan.y && other.block.size == plan.block.size){ + player.unit().plans().remove(other); + player.unit().addBuild(copy); + } } - } - rotation = plan.rotation; - }else{ - tryBreakBlock(tile.x, tile.y); + rotation = plan.rotation; + }else{ + tryBreakBlock(tile.x, tile.y); + } } } - } - //move all current plans to removal array so they fade out - removals.addAll(selectPlans.select(r -> !r.breaking)); - selectPlans.clear(); - selecting = false; - }).visible(() -> !selectPlans.isEmpty()).name("confirmplace"); + //move all current plans to removal array so they fade out + removals.addAll(selectPlans.select(r -> !r.breaking)); + selectPlans.clear(); + selecting = false; + } + }).visible(() -> !selectPlans.isEmpty() || schematicMode || rebuildMode).update(i -> { + i.getStyle().imageUp = schematicMode || rebuildMode ? Icon.wrench : Icon.ok; + i.setChecked(rebuildMode); + + }).name("confirmplace"); } boolean showCancel(){ @@ -369,6 +379,8 @@ public class MobileInput extends InputHandler implements GestureListener{ //draw schematic selection if(mode == schematicSelect){ drawSelection(lineStartX, lineStartY, lastLineX, lastLineY, Vars.maxSchematicSize); + }else if(mode == rebuildSelect){ + drawRebuildSelection(lineStartX, lineStartY, lastLineX, lastLineY); } drawCommanded(); @@ -443,6 +455,11 @@ public class MobileInput extends InputHandler implements GestureListener{ //endregion //region input events, overrides + @Override + public boolean isRebuildSelecting(){ + return rebuildMode; + } + @Override protected int schemOriginX(){ Tmp.v1.setZero(); @@ -496,7 +513,8 @@ public class MobileInput extends InputHandler implements GestureListener{ //call tap events if(pointer == 0 && !selecting){ if(schematicMode && block == null){ - mode = schematicSelect; + mode = rebuildMode ? rebuildSelect : schematicSelect; + //engage schematic selection mode int tileX = tileX(screenX); int tileY = tileY(screenY); @@ -546,6 +564,9 @@ public class MobileInput extends InputHandler implements GestureListener{ } schematicMode = false; mode = none; + }else if(mode == rebuildSelect){ + rebuildArea(lineStartX, lineStartY, lastLineX, lastLineY); + mode = none; }else{ Tile tile = tileAt(screenX, screenY); @@ -780,11 +801,15 @@ public class MobileInput extends InputHandler implements GestureListener{ } //stop select when not in schematic mode - if(!schematicMode && mode == schematicSelect){ + if(!schematicMode && (mode == schematicSelect || mode == rebuildSelect)){ mode = none; } - if(mode == schematicSelect){ + if(!rebuildMode && mode == rebuildSelect){ + mode = none; + } + + if(mode == schematicSelect || mode == rebuildSelect){ lastLineX = rawTileX(); lastLineY = rawTileY(); autoPan(); diff --git a/core/src/mindustry/ui/dialogs/JoinDialog.java b/core/src/mindustry/ui/dialogs/JoinDialog.java index 64ad30b12c..5db313a075 100644 --- a/core/src/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/mindustry/ui/dialogs/JoinDialog.java @@ -59,12 +59,12 @@ public class JoinDialog extends BaseDialog{ loadServers(); //mobile players don't get information >:( - boolean infoButton = !steam && !Core.app.isMobile(); + boolean infoButton = !steam && !mobile; if(infoButton) buttons.add().width(60f); buttons.add().growX().width(-1); - addCloseButton(Core.app.isMobile() ? 190f : 210f); + addCloseButton(mobile ? 190f : 210f); buttons.button("@server.add", Icon.add, () -> { renaming = null; diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index 52527ad081..3ab79fb947 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -184,7 +184,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ b.add(planet.localizedName).color(Pal.accent).style(Styles.outlineLabel); b.row(); b.image(new TextureRegionDrawable(tex)).grow().scaling(Scaling.fit); - }, Styles.togglet, () -> selected[0] = planet).size(Core.app.isMobile() ? 220f : 320f).group(group); + }, Styles.togglet, () -> selected[0] = planet).size(mobile ? 220f : 320f).group(group); i ++; } diff --git a/core/src/mindustry/ui/fragments/HintsFragment.java b/core/src/mindustry/ui/fragments/HintsFragment.java index 0379bbde93..3bed648fdc 100644 --- a/core/src/mindustry/ui/fragments/HintsFragment.java +++ b/core/src/mindustry/ui/fragments/HintsFragment.java @@ -174,7 +174,7 @@ public class HintsFragment{ payloadDrop(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().any(), () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty()), waveFire(() -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0), generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)), - rebuildSelect(visibleDesktop, () -> state.rules.defaultTeam.data().plans.size >= 10, () -> Core.input.keyDown(Binding.rebuild_select)), + rebuildSelect(() -> state.rules.defaultTeam.data().plans.size >= 10, () -> control.input.isRebuildSelecting()), guardian(() -> state.boss() != null && isSerpulo() && state.boss().armor >= 4, () -> state.boss() == null), factoryControl(() -> !(state.isCampaign() && state.rules.sector.preset == SectorPresets.onset) && state.rules.defaultTeam.data().getBuildings(Blocks.tankFabricator).size + state.rules.defaultTeam.data().getBuildings(Blocks.groundFactory).size > 0, () -> ui.hints.events.contains("factorycontrol")),