Mobile rebuild button support

This commit is contained in:
Anuken
2023-05-11 13:41:45 -04:00
parent 74f1688dd2
commit d34631458e
7 changed files with 90 additions and 63 deletions

View File

@@ -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.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.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 = 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 = 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. hint.conveyorPathfind.mobile = Enable \uE844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.

View File

@@ -12,20 +12,15 @@ import arc.scene.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.util.*; import arc.util.*;
import mindustry.*; import mindustry.*;
import mindustry.content.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.input.Placement.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*; import mindustry.world.*;
import java.util.*;
import static arc.Core.*; import static arc.Core.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
import static mindustry.input.PlaceMode.*; import static mindustry.input.PlaceMode.*;
@@ -119,19 +114,7 @@ public class DesktopInput extends InputHandler{
if(Core.input.keyDown(Binding.schematic_select)){ if(Core.input.keyDown(Binding.schematic_select)){
drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize); drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize);
}else if(Core.input.keyDown(Binding.rebuild_select)){ }else if(Core.input.keyDown(Binding.rebuild_select)){
//TODO color? drawRebuildSelection(schemX, schemY, cursorX, cursorY);
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);
}
}
} }
} }
@@ -529,20 +512,8 @@ public class DesktopInput extends InputHandler{
schemX = -1; schemX = -1;
schemY = -1; schemY = -1;
}else if(input.keyRelease(Binding.rebuild_select)){ }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<BlockPlan> 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; schemX = -1;
schemY = -1; schemY = -1;
} }

View File

@@ -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); 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){ protected void drawBreakSelection(int x1, int y1, int x2, int y2){
drawBreakSelection(x1, y1, x2, y2, maxLength); 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<BlockPlan> 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){ public void tryBreakBlock(int x, int y){
if(validBreak(x, y)){ if(validBreak(x, y)){
breakBlock(x, y); breakBlock(x, y);

View File

@@ -55,7 +55,7 @@ public class MobileInput extends InputHandler implements GestureListener{
/** Whether the player is currently shifting all placed tiles. */ /** Whether the player is currently shifting all placed tiles. */
public boolean selecting; public boolean selecting;
/** Whether the player is currently in line-place mode. */ /** Whether the player is currently in line-place mode. */
public boolean lineMode, schematicMode; public boolean lineMode, schematicMode, rebuildMode;
/** Current place mode. */ /** Current place mode. */
public PlaceMode mode = none; public PlaceMode mode = none;
/** Whether no recipe was available when switching to break mode. */ /** Whether no recipe was available when switching to break mode. */
@@ -208,6 +208,8 @@ public class MobileInput extends InputHandler implements GestureListener{
if(schematicMode){ if(schematicMode){
block = null; block = null;
mode = none; mode = none;
}else{
rebuildMode = false;
} }
} }
}).update(i -> { }).update(i -> {
@@ -219,37 +221,45 @@ public class MobileInput extends InputHandler implements GestureListener{
}); });
//confirm button //confirm button
table.button(Icon.ok, Styles.clearNonei, () -> { table.button(Icon.ok, Styles.clearNoneTogglei, () -> {
for(BuildPlan plan : selectPlans){ if(schematicMode){
Tile tile = plan.tile(); rebuildMode = !rebuildMode;
}else{
for(BuildPlan plan : selectPlans){
Tile tile = plan.tile();
//actually place/break all selected blocks //actually place/break all selected blocks
if(tile != null){ if(tile != null){
if(!plan.breaking){ if(!plan.breaking){
if(validPlace(plan.x, plan.y, plan.block, plan.rotation)){ if(validPlace(plan.x, plan.y, plan.block, plan.rotation)){
BuildPlan other = getPlan(plan.x, plan.y, plan.block.size, null); BuildPlan other = getPlan(plan.x, plan.y, plan.block.size, null);
BuildPlan copy = plan.copy(); BuildPlan copy = plan.copy();
if(other == null){ if(other == null){
player.unit().addBuild(copy); player.unit().addBuild(copy);
}else if(!other.breaking && other.x == plan.x && other.y == plan.y && other.block.size == plan.block.size){ }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().plans().remove(other);
player.unit().addBuild(copy); player.unit().addBuild(copy);
}
} }
}
rotation = plan.rotation; rotation = plan.rotation;
}else{ }else{
tryBreakBlock(tile.x, tile.y); tryBreakBlock(tile.x, tile.y);
}
} }
} }
}
//move all current plans to removal array so they fade out //move all current plans to removal array so they fade out
removals.addAll(selectPlans.select(r -> !r.breaking)); removals.addAll(selectPlans.select(r -> !r.breaking));
selectPlans.clear(); selectPlans.clear();
selecting = false; selecting = false;
}).visible(() -> !selectPlans.isEmpty()).name("confirmplace"); }
}).visible(() -> !selectPlans.isEmpty() || schematicMode || rebuildMode).update(i -> {
i.getStyle().imageUp = schematicMode || rebuildMode ? Icon.wrench : Icon.ok;
i.setChecked(rebuildMode);
}).name("confirmplace");
} }
boolean showCancel(){ boolean showCancel(){
@@ -369,6 +379,8 @@ public class MobileInput extends InputHandler implements GestureListener{
//draw schematic selection //draw schematic selection
if(mode == schematicSelect){ if(mode == schematicSelect){
drawSelection(lineStartX, lineStartY, lastLineX, lastLineY, Vars.maxSchematicSize); drawSelection(lineStartX, lineStartY, lastLineX, lastLineY, Vars.maxSchematicSize);
}else if(mode == rebuildSelect){
drawRebuildSelection(lineStartX, lineStartY, lastLineX, lastLineY);
} }
drawCommanded(); drawCommanded();
@@ -443,6 +455,11 @@ public class MobileInput extends InputHandler implements GestureListener{
//endregion //endregion
//region input events, overrides //region input events, overrides
@Override
public boolean isRebuildSelecting(){
return rebuildMode;
}
@Override @Override
protected int schemOriginX(){ protected int schemOriginX(){
Tmp.v1.setZero(); Tmp.v1.setZero();
@@ -496,7 +513,8 @@ public class MobileInput extends InputHandler implements GestureListener{
//call tap events //call tap events
if(pointer == 0 && !selecting){ if(pointer == 0 && !selecting){
if(schematicMode && block == null){ if(schematicMode && block == null){
mode = schematicSelect; mode = rebuildMode ? rebuildSelect : schematicSelect;
//engage schematic selection mode //engage schematic selection mode
int tileX = tileX(screenX); int tileX = tileX(screenX);
int tileY = tileY(screenY); int tileY = tileY(screenY);
@@ -546,6 +564,9 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
schematicMode = false; schematicMode = false;
mode = none; mode = none;
}else if(mode == rebuildSelect){
rebuildArea(lineStartX, lineStartY, lastLineX, lastLineY);
mode = none;
}else{ }else{
Tile tile = tileAt(screenX, screenY); Tile tile = tileAt(screenX, screenY);
@@ -780,11 +801,15 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
//stop select when not in schematic mode //stop select when not in schematic mode
if(!schematicMode && mode == schematicSelect){ if(!schematicMode && (mode == schematicSelect || mode == rebuildSelect)){
mode = none; mode = none;
} }
if(mode == schematicSelect){ if(!rebuildMode && mode == rebuildSelect){
mode = none;
}
if(mode == schematicSelect || mode == rebuildSelect){
lastLineX = rawTileX(); lastLineX = rawTileX();
lastLineY = rawTileY(); lastLineY = rawTileY();
autoPan(); autoPan();

View File

@@ -59,12 +59,12 @@ public class JoinDialog extends BaseDialog{
loadServers(); loadServers();
//mobile players don't get information >:( //mobile players don't get information >:(
boolean infoButton = !steam && !Core.app.isMobile(); boolean infoButton = !steam && !mobile;
if(infoButton) buttons.add().width(60f); if(infoButton) buttons.add().width(60f);
buttons.add().growX().width(-1); buttons.add().growX().width(-1);
addCloseButton(Core.app.isMobile() ? 190f : 210f); addCloseButton(mobile ? 190f : 210f);
buttons.button("@server.add", Icon.add, () -> { buttons.button("@server.add", Icon.add, () -> {
renaming = null; renaming = null;

View File

@@ -184,7 +184,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
b.add(planet.localizedName).color(Pal.accent).style(Styles.outlineLabel); b.add(planet.localizedName).color(Pal.accent).style(Styles.outlineLabel);
b.row(); b.row();
b.image(new TextureRegionDrawable(tex)).grow().scaling(Scaling.fit); 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 ++; i ++;
} }

View File

@@ -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()), 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), 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)), 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), guardian(() -> state.boss() != null && isSerpulo() && state.boss().armor >= 4, () -> state.boss() == null),
factoryControl(() -> !(state.isCampaign() && state.rules.sector.preset == SectorPresets.onset) && 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")), state.rules.defaultTeam.data().getBuildings(Blocks.tankFabricator).size + state.rules.defaultTeam.data().getBuildings(Blocks.groundFactory).size > 0, () -> ui.hints.events.contains("factorycontrol")),